---
title: "Calculate Moon phase geometry or a bounded primary-phase calendar"
method: POST
path: "/api/astro/moon-phases"
tags: ["Calculations"]
---

# Calculate Moon phase geometry or a bounded primary-phase calendar

`POST /api/astro/moon-phases`

## Request

- Base URL: `https://api.cosmicephemeris.com`
- URL: `https://api.cosmicephemeris.com/api/astro/moon-phases`
- Auth: one of:
  - HTTP bearer
  - API key in header `x-api-key`

Explicit instant mode returns a named display sector, Moon-minus-Sun ecliptic longitude and separately calculated spherical illuminated fraction. Calendar mode returns primary longitude crossings, not eclipse predictions or visibility. Dates 1800–2200; calendar spans at most 366 UTC days. No coordinates, zodiac, user kernels or arbitrary search tuning. Uses existing DE440 and bundled time-scale data; future UTC assumes the bundled leap-second schedule. Current: one-second output and millisecond root convergence are not accuracy guarantees. Independent 2026 USNO comparison has a 60-second tolerance; broader epoch/time-scale acceptance remains separate. Each admitted request reserves one standard monthly quota unit, including invalid inputs and timeouts. All plans; no automatic retries. Source availability does not establish deployment. Each admitted request reserves one monthly usage unit before route validation or engine work; failed or timed-out admitted attempts are not refunded. Do not automatically retry.
Historical mode uses an explicit BCE/CE date object and UT1 conventions. Its response is the versioned historical envelope, not the modern UTC envelope. Read result for calculation fields and metadata for limits and uncertainty.

## Request body

- union
  - union
    - MoonPhaseInstantRequest
      - `mode` 'instant', required
      - `at` CivilTimeInput, required
        - `date` string, date, required: Valid Gregorian YYYY-MM-DD local civil date, inclusive 1800-01-01 through 2200-12-31. Calendar validity and timezone conversion are checked by the server.
        - `time` string, required: HH:MM or HH:MM:SS; no offset in this field. Use timezone to select the civil-time zone.
        - `timezone` string
      - `display_timezone` string
    - MoonPhaseCalendarRequest: Start-inclusive/end-exclusive interval, greater than zero and at most 366 elapsed UTC days after civil-time conversion. Both civil dates must be within 1800–2200; UTC coverage is separately checked. Invalid calendars, DST gaps/folds and unavailable timezones return 400.
      - `mode` 'calendar', required
      - `start` CivilTimeInput, required
        - `date` string, date, required: Valid Gregorian YYYY-MM-DD local civil date, inclusive 1800-01-01 through 2200-12-31. Calendar validity and timezone conversion are checked by the server.
        - `time` string, required: HH:MM or HH:MM:SS; no offset in this field. Use timezone to select the civil-time zone.
        - `timezone` string
      - `end` CivilTimeInput, required
        - `date` string, date, required: Valid Gregorian YYYY-MM-DD local civil date, inclusive 1800-01-01 through 2200-12-31. Calendar validity and timezone conversion are checked by the server.
        - `time` string, required: HH:MM or HH:MM:SS; no offset in this field. Use timezone to select the civil-time zone.
        - `timezone` string
      - `display_timezone` string
      - `include_ical` boolean: Opt in to result.ical: a bounded RFC 5545 UTC point-event export, or null when no events occur. Calendar mode only. No extra quota unit, subscription feed, reminders or external calendar writes.
  - union: Explicit historical mode, 1000 BCE (BC)–2500 CE (AD). No year zero, implicit calendar, UTC or IANA zone. Preserve tool-specific mathematical, geographic and search limits; calendar/time conventions and estimated Delta-T are not certified historical accuracy.
    - object
      - `mode` 'instant', required
      - `at` object, required
        - `date` HistoricalDate, required: Explicit civil date, 1000 BCE (BC)–2500 CE (AD); no year zero. Calendar validity is checked by the server. Available only on documented connected historical operations, with explicit UT1/fixed-offset conventions.
          - `year` integer, required
          - `era` 'BCE' | 'CE', required: Display BCE (BC) / CE (AD); API values remain BCE / CE. No year zero.
          - `month` integer, required
          - `day` integer, required
          - `calendar` 'proleptic_gregorian' | 'proleptic_julian', required: Explicit choice; applies the selected calendar rules throughout history without a regional adoption switch.
        - `time` string, required: HH:MM or HH:MM:SS; no offset in this field. Use timezone to select the civil-time zone.
        - `timezone` string, required: Explicit UT1 or fixed offset UT1+/-HH:MM[:SS], within 14 hours. Local clock minus offset yields UT1, not UTC. No IANA timezone inference. Original offset spelling is preserved.
      - `display_timezone` string: Explicit UT1 or fixed offset UT1+/-HH:MM[:SS], within 14 hours. Local clock minus offset yields UT1, not UTC. No IANA timezone inference. Original offset spelling is preserved.
    - object: Start-inclusive/end-exclusive interval, greater than zero and at most 366 elapsed UTC days after civil-time conversion. Both civil dates must be within 1800–2200; UTC coverage is separately checked. Invalid calendars, DST gaps/folds and unavailable timezones return 400.
      - `mode` 'calendar', required
      - `start` object, required
        - `date` HistoricalDate, required: Explicit civil date, 1000 BCE (BC)–2500 CE (AD); no year zero. Calendar validity is checked by the server. Available only on documented connected historical operations, with explicit UT1/fixed-offset conventions.
          - `year` integer, required
          - `era` 'BCE' | 'CE', required: Display BCE (BC) / CE (AD); API values remain BCE / CE. No year zero.
          - `month` integer, required
          - `day` integer, required
          - `calendar` 'proleptic_gregorian' | 'proleptic_julian', required: Explicit choice; applies the selected calendar rules throughout history without a regional adoption switch.
        - `time` string, required: HH:MM or HH:MM:SS; no offset in this field. Use timezone to select the civil-time zone.
        - `timezone` string, required: Explicit UT1 or fixed offset UT1+/-HH:MM[:SS], within 14 hours. Local clock minus offset yields UT1, not UTC. No IANA timezone inference. Original offset spelling is preserved.
      - `end` object, required
        - `date` HistoricalDate, required: Explicit civil date, 1000 BCE (BC)–2500 CE (AD); no year zero. Calendar validity is checked by the server. Available only on documented connected historical operations, with explicit UT1/fixed-offset conventions.
          - `year` integer, required
          - `era` 'BCE' | 'CE', required: Display BCE (BC) / CE (AD); API values remain BCE / CE. No year zero.
          - `month` integer, required
          - `day` integer, required
          - `calendar` 'proleptic_gregorian' | 'proleptic_julian', required: Explicit choice; applies the selected calendar rules throughout history without a regional adoption switch.
        - `time` string, required: HH:MM or HH:MM:SS; no offset in this field. Use timezone to select the civil-time zone.
        - `timezone` string, required: Explicit UT1 or fixed offset UT1+/-HH:MM[:SS], within 14 hours. Local clock minus offset yields UT1, not UTC. No IANA timezone inference. Original offset spelling is preserved.
      - `display_timezone` string: Explicit UT1 or fixed offset UT1+/-HH:MM[:SS], within 14 hours. Local clock minus offset yields UT1, not UTC. No IANA timezone inference. Original offset spelling is preserved.
      - `include_ical` unknown

## Response `200`

Mode-specific geometry/calendar envelope.

- union
  - MoonPhaseInstantResponse
    - `type` 'moon_phases', required
    - `status` 'current', required
    - `mode` 'instant', required
    - `result` MoonPhaseSnapshot, required
      - `utc` string, date-time, required: Normalized UTC timestamp; fractional seconds may be present.
      - `local` string, date-time, required
      - `timezone` string, required
      - `phase_sector` 'new_moon' | 'waxing_crescent' | 'first_quarter' | 'waxing_gibbous' | 'full_moon' | 'waning_gibbous' | 'last_quarter' | 'waning_crescent', required: Nearest 45-degree display sector, not an exact event or measured brightness.
      - `elongation_degrees` number, required: Moon minus Sun ecliptic longitude, not great-circle angular separation.
      - `longitude_cycle` 'waxing' | 'waning', required: Waxing for longitude difference below 180 degrees; not the derivative of illuminated area.
      - `illuminated_fraction` number, required
      - `model` 'de440-geocentric-moon-phase-v1', required
    - `metadata` MoonPhaseMetadata, required
      - `frame` 'apparent_geocentric_ecliptic_of_date', required
      - `timescale_data` 'bundled-skyfield', required
      - `phase_definition` 'moon_minus_sun_ecliptic_longitude', required
      - `illumination_model` 'spherical_geometric_no_eclipse_shadow', required
      - `interpretations` false, required
  - MoonPhaseCalendarResponse
    - `type` 'moon_phases', required
    - `status` 'current', required
    - `mode` 'calendar', required
    - `result` MoonPhaseCalendar, required
      - `start_utc` string, date-time, required: Normalized UTC timestamp; fractional seconds may be present.
      - `end_utc` string, date-time, required: Normalized UTC timestamp; fractional seconds may be present.
      - `timezone` string, required
      - `events` MoonPhaseEvent[], required
        - union
          - object
            - `phase` 'new_moon', required
            - `target_degrees` 0, required
            - `utc` string, date-time, required: Normalized UTC timestamp; fractional seconds may be present.
            - `local` string, date-time, required
          - object
            - `phase` 'first_quarter', required
            - `target_degrees` 90, required
            - `utc` string, date-time, required: Normalized UTC timestamp; fractional seconds may be present.
            - `local` string, date-time, required
          - object
            - `phase` 'full_moon', required
            - `target_degrees` 180, required
            - `utc` string, date-time, required: Normalized UTC timestamp; fractional seconds may be present.
            - `local` string, date-time, required
          - object
            - `phase` 'last_quarter', required
            - `target_degrees` 270, required
            - `utc` string, date-time, required: Normalized UTC timestamp; fractional seconds may be present.
            - `local` string, date-time, required
      - `model` 'de440-geocentric-moon-phase-v1', required
      - `interval` 'start_inclusive_end_exclusive', required
      - `timestamp_resolution_seconds` 1, required
      - `search_tolerance_seconds` 0.001, required: Numerical root convergence only; not a physical event-time accuracy guarantee.
      - `ical` string, nullable: Present only for include_ical:true. Save the decoded string as UTF-8 .ics; CRLF and folded content lines are already supplied. Null means no events and no file. UTC DTSTART preserves instants across calendar display timezones. UIDs bind model, phase and reported second; DTSTAMP is export assembly time and can change across calls. No METHOD, recurrence, attendees, organizer, alarms, attachments or subscription URL.
    - `metadata` MoonPhaseMetadata, required
      - `frame` 'apparent_geocentric_ecliptic_of_date', required
      - `timescale_data` 'bundled-skyfield', required
      - `phase_definition` 'moon_minus_sun_ecliptic_longitude', required
      - `illumination_model` 'spherical_geometric_no_eclipse_shadow', required
      - `interpretations` false, required
  - HistoricalMoonPhasesMoonPhaseResponse
    - `schema` 'cosmicephemeris-historical-calculation-v1', required
    - `status` 'historical', required
    - `type` 'moon-phases', required
    - `input` union, required: Explicit historical mode, 1000 BCE (BC)–2500 CE (AD). No year zero, implicit calendar, UTC or IANA zone. Preserve tool-specific mathematical, geographic and search limits; calendar/time conventions and estimated Delta-T are not certified historical accuracy.
      - object
        - `mode` 'instant', required
        - `at` object, required
          - `date` HistoricalDate, required: Explicit civil date, 1000 BCE (BC)–2500 CE (AD); no year zero. Calendar validity is checked by the server. Available only on documented connected historical operations, with explicit UT1/fixed-offset conventions.
            - `year` integer, required
            - `era` 'BCE' | 'CE', required: Display BCE (BC) / CE (AD); API values remain BCE / CE. No year zero.
            - `month` integer, required
            - `day` integer, required
            - `calendar` 'proleptic_gregorian' | 'proleptic_julian', required: Explicit choice; applies the selected calendar rules throughout history without a regional adoption switch.
          - `time` string, required: HH:MM or HH:MM:SS; no offset in this field. Use timezone to select the civil-time zone.
          - `timezone` string, required: Explicit UT1 or fixed offset UT1+/-HH:MM[:SS], within 14 hours. Local clock minus offset yields UT1, not UTC. No IANA timezone inference. Original offset spelling is preserved.
        - `display_timezone` string: Explicit UT1 or fixed offset UT1+/-HH:MM[:SS], within 14 hours. Local clock minus offset yields UT1, not UTC. No IANA timezone inference. Original offset spelling is preserved.
      - object: Start-inclusive/end-exclusive interval, greater than zero and at most 366 elapsed UTC days after civil-time conversion. Both civil dates must be within 1800–2200; UTC coverage is separately checked. Invalid calendars, DST gaps/folds and unavailable timezones return 400.
        - `mode` 'calendar', required
        - `start` object, required
          - `date` HistoricalDate, required: Explicit civil date, 1000 BCE (BC)–2500 CE (AD); no year zero. Calendar validity is checked by the server. Available only on documented connected historical operations, with explicit UT1/fixed-offset conventions.
            - `year` integer, required
            - `era` 'BCE' | 'CE', required: Display BCE (BC) / CE (AD); API values remain BCE / CE. No year zero.
            - `month` integer, required
            - `day` integer, required
            - `calendar` 'proleptic_gregorian' | 'proleptic_julian', required: Explicit choice; applies the selected calendar rules throughout history without a regional adoption switch.
          - `time` string, required: HH:MM or HH:MM:SS; no offset in this field. Use timezone to select the civil-time zone.
          - `timezone` string, required: Explicit UT1 or fixed offset UT1+/-HH:MM[:SS], within 14 hours. Local clock minus offset yields UT1, not UTC. No IANA timezone inference. Original offset spelling is preserved.
        - `end` object, required
          - `date` HistoricalDate, required: Explicit civil date, 1000 BCE (BC)–2500 CE (AD); no year zero. Calendar validity is checked by the server. Available only on documented connected historical operations, with explicit UT1/fixed-offset conventions.
            - `year` integer, required
            - `era` 'BCE' | 'CE', required: Display BCE (BC) / CE (AD); API values remain BCE / CE. No year zero.
            - `month` integer, required
            - `day` integer, required
            - `calendar` 'proleptic_gregorian' | 'proleptic_julian', required: Explicit choice; applies the selected calendar rules throughout history without a regional adoption switch.
          - `time` string, required: HH:MM or HH:MM:SS; no offset in this field. Use timezone to select the civil-time zone.
          - `timezone` string, required: Explicit UT1 or fixed offset UT1+/-HH:MM[:SS], within 14 hours. Local clock minus offset yields UT1, not UTC. No IANA timezone inference. Original offset spelling is preserved.
        - `display_timezone` string: Explicit UT1 or fixed offset UT1+/-HH:MM[:SS], within 14 hours. Local clock minus offset yields UT1, not UTC. No IANA timezone inference. Original offset spelling is preserved.
        - `include_ical` unknown
    - `result` object, required: Complete historical calculation adapter result. Times are explicit UT1 date records, never UTC strings; derived times may include fractional seconds and years outside the input range.
    - `metadata` object, required
      - `time_standard` 'UT1', required
      - `historical_accuracy_certified` unknown, required
      - `warnings` string[], required

## Other responses

- `400`: Invalid request, malformed JSON, out-of-range date/location, unknown model, invalid timezone or ambiguous/nonexistent clock-change time. Invalid attempts reaching quota reservation consume one unit.
- `401`: Missing, invalid, revoked API key or unavailable activated key owner. Dashboard cookies do not authenticate calculation routes.
- `403`: Origin not allowed by production CORS policy. Server-to-server requests can omit Origin.
- `404`: Wrong/case-variant/noncanonical or trailing-slash route; public paths have no version prefix.
- `413`: Request exceeds the body limit; gateway JSON is capped at 128 KiB. Edge failures may be HTML.
- `429`: Monthly quota exhausted, per-user two-request concurrency reached, or nginx rate/connection admission refused. Retry-After: 2 is sent for application per-user concurrency only, not a promise that monthly quota resets in two seconds.
- `500`: Bounded gateway/database/internal failure. An admitted attempt can still consume quota.
- `502`: Engine unavailable, unsuccessful internal server response or invalid upstream JSON. No engine internals are exposed.
- `503`: Four-request global calculation pool full (Retry-After: 2), maintenance or upstream service unavailable.
- `504`: Application engine timeout: 15 seconds normally; planetary events, house ingresses, aspect windows, event calendar, eclipse geometry, electional search, and event-rule search use 30 seconds; Nakshatra Timeline plus the explicitly enumerated readiness, robustness, location, uncertainty, and electional-audit family use 60 seconds. Timer includes response-body parsing; an admitted timeout consumes quota.

---

[API](https://skmtc.dev/cosmicephemeris/apis/cosmic-ephemeris-calculation-api.md) · [All operations](https://skmtc.dev/cosmicephemeris/apis/cosmic-ephemeris-calculation-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cosmicephemeris/apis/cosmic-ephemeris-calculation-api/revisions/f041e924cea3?raw)
