---
title: "Calculate Synastry"
method: POST
path: "/comparative/synastry"
tags: ["comparative"]
---

# Calculate Synastry

`POST /comparative/synastry`

## Request

- Base URL: `https://api.openephemeris.com`
- URL: `https://api.openephemeris.com/comparative/synastry`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-OpenEphemeris-API-Key`
  - API key in header `X-API-Key`
  - API key in header `X-Service-Key`

Calculate a synastry chart (comparison between two subjects).

🤖 AI-optimized output available — add `format=llm` to reduce payload ~65%.

## Query parameters

- `format` string

## Request body

- SynastryRequest: Synastry request comparing two natal subjects.
  - `configuration` ChartConfiguration: Legacy configuration model. New integrations should use NatalConfig with object_set and node_source instead of include_* booleans.
    - `additional_objects` string[]: Explicit body slugs to compute in addition to the base 10-planet roster (comparative/synastry and comparative/composite only compute the classical planets by default). Ephemeris body slugs: sun, moon, mercury, venus, mars, jupiter, saturn, uranus, neptune, pluto, north_node, true_node, lilith, lilith_true, lilith_interpolated, chiron, pholus, eris, sedna, makemake, haumea, quaoar, orcus, ixion, varuna, cupido, hades, zeus, kronos, apollon, admetos, vulkanus, poseidon, eros, sappho, lilith_asteroid, nessus, chariklo, amor, betulia, icarus, apollo, adonis, phaethon, astraea, hebe, flora, metis, parthenope, victoria, egeria, irene, massalia, isis, anubis, odysseus, tolosa, medusa, ambrosia, aletheia, thule, polyxo, myrrha, valentine, hercynia, nestor, siva, atlantis, aphrodite, prometheus, epimetheus, shaposhnikov, lick, huya, ceres, pallas, juno, vesta, hygiea, eunomia, psyche, europa_asteroid, cybele, sylvia, thisbe, camilla, iris, davida, euphrosyne, interamnia. Unknown slugs are ignored.
    - `ascendant_on_left` boolean: When true (default), the Ascendant is placed at the 9 o'clock (West/left) position � matching the convention used by Astro.com, Solar Fire, and all major astrology software. Set to false to use the ecliptic-fixed (Aries-pinned) orientation instead.
    - `aspect_orbs` object: Caller-supplied orb allowances in degrees, keyed by aspect name (conjunction, opposition, trine, square, sextile, and the minors quincunx, semisextile, semisquare, sesquiquadrate, quintile, biquintile). Overrides the default table for the aspects named; aspects not named keep their defaults, and naming a minor is what turns it on. An unknown aspect name is rejected with 422 rather than ignored, because a silently dropped override returns a chart scored against a table the caller did not choose. Setting an orb to 0 turns that aspect off entirely. Honoured on the routes that compute an aspect grid: /comparative/composite, /comparative/natal-transits, /comparative/synastry and /ephemeris/progressed.
    - `asteroid_groups` AsteroidGroupEnum[]: Optional thematic asteroid groups to include, additive on top of the base 10-planet roster: major (Ceres/Pallas/Juno/Vesta), centaur (Chiron/Pholus), main_belt (the 12 sb441-n16 minor asteroids), tno (the 8 trans-Neptunian objects: Eris, Sedna, Makemake, Haumea, Quaoar, Orcus, Ixion, Varuna). muse is accepted but not yet computed (no kernel loaded).
    - `ayanamsa` string: Ayanamsa for sidereal calculations
    - `house_system` 'P' | 'K' | 'O' | 'R' | 'C' | 'E' | 'W': Supported house systems.
    - `include_chiron` boolean: Include Chiron in calculations
    - `include_lilith` boolean: Include Black Moon Lilith
  - `enhanced_options` EnhancedCalculationOptions: Options for enhanced natal chart calculations.
    - `aspect_patterns` boolean: Identify aspect patterns
    - `element_balance` boolean: Calculate elemental balance
    - `elongations` boolean: Compute Sun-relative elongation metrics for major bodies (separation, signed delta, east/west).
    - `harmonic_numbers` integer[]: Harmonic numbers to calculate (default: [4, 5, 7, 9])
    - `hemisphere_emphasis` boolean: Analyze hemisphere emphasis
    - `hermetic_lots_selection` string[]: Optional list of Hermetic lot identifiers to calculate (aliases accepted: arabic_parts_selection). If omitted, defaults to the canonical selection.
    - `human_design_gates` boolean: Compute Human Design / I Ching gate + line mappings from ecliptic longitude.
    - `include_fixed_stars` boolean: DEPRECATED. Fixed-star computation is configured via configuration.fixed_star_options.include. This field is accepted for backward compatibility and may be removed in a future release.
    - `include_harmonics` boolean: Include harmonic chart positions
    - `include_hermetic_lots` boolean: Calculate Hermetic lots
    - `include_midpoints` boolean: Calculate midpoints between planet pairs
    - `lunar_phase` boolean: Compute lunar phase (name, illumination, phase angle, waxing/waning, and days-to-new/full).
    - `sect_determination` boolean: Perform sect determination
    - `solar_relationships` boolean: Compute solar relationship / visibility classifications (e.g., cazimi/combust/under-beams) and Mercury/Venus morning/evening star context.
    - `void_of_course` boolean: Compute Void-of-Course Moon status and window (bounded search within current sign).
  - `include_visual` boolean: If true, a full visual SVG or PNG output will be rendered and returned alongside the chart data. Note: Visuals incur a +2 credit surcharge.
  - `subject_a` SubjectRequest, required: Subject identity and birth data used to compute a chart.
    - `birth_datetime` DateTimeInput, required: Date/time input in ISO-8601, component, or Julian day form. A value that states a clock time must also state its zone, either as a suffix on the string or via the `timezone` field below.
      - `components` object: Date/time components (year, month, day, and optionally hour, minute, second). If hour/minute are present, pass `timezone` alongside them; without it the request is rejected with 400 ambiguous_datetime. Omit the clock entirely and the date resolves to 12:00 UTC.
      - `iso` string: ISO-8601 datetime (supported range 1550–2650 CE, JPL DE440). If it states a clock time it must carry its zone: either a 'Z'/±HH:MM suffix on the string ("1987-07-15T09:01:00-05:00"), or a `timezone` passed alongside it. A zone-less clock time is rejected with 400 ambiguous_datetime — it is not read as UTC. A date-only value ("1987-07-15") has no clock to be ambiguous about and resolves to 12:00 UTC.
      - `julian_day` number, double: Julian Day Number (always UTC-based, so it needs no zone)
      - `timezone` TimezoneInput: Timezone input using IANA names or UTC offsets.
        - `fold_preference` 'earlier' | 'later': Which occurrence to use when the naive local datetime falls in a fall-back fold (a repeated hour): 'earlier' (default — first occurrence) or 'later'. Only meaningful for naive datetimes; the response reports datetime_status=ambiguous_fold either way so the ambiguity can be surfaced to the user.
        - `iana_name` string: IANA timezone name
        - `time_standard` 'auto' | 'standard' | 'daylight': How to interpret a naive local datetime when this zone is applied. 'auto' (default): resolve through the historical-correction overlay where one covers the region/era, then IANA tzdata. 'standard': force the zone's standard (non-daylight) offset — for callers who KNOW the recorded time was standard time regardless of what tzdata believes. 'daylight': force standard+1h. Forcing either marks the resolution tz_confidence=client_override. Ignored when the datetime carries its own Z/±HH:MM suffix or when utc_offset is used.
        - `utc_offset` number: UTC offset in hours
    - `birth_location` BirthLocation, required: Location context for birth data: coordinates plus timezone.
      - `city` string: City name
      - `country` string: Country
      - `elevation` number: Elevation in meters. Accepted and echoed back unchanged; it does not affect planetary positions, which are computed geocentrically. Elevation changes results only where it is taken as the `elev` query parameter: /eclipse/solar/local (local circumstances) and /time/solar-event plus /ephemeris/agro/* (horizon rise/set times).
      - `latitude` CoordinateInput, required: Flexible coordinate input supporting multiple formats.
        - `components` object: Separate degree components with direction
        - `decimal` number: Decimal degrees (-90 to 90 for lat, -180 to 180 for lon)
        - `dms` string: Degrees, minutes, seconds string (e.g., '40°42'46"N')
      - `location_name` string: Birthplace display name (e.g. "Dallas, TX"). Never affects calculations — coordinates and timezone are the only location facts the engine reads. Echoed back verbatim where the response carries an echo block: as subject.location_name on chart routes that echo a subject (natal, draconic, progressed, synastry, natal-transits, overlay, natal/batch items, predictive transit-chart), inside search_summary on /electional/natal-angle-crossings, metadata on /acg/midpoints, and natal on /human-design/transit-chart. Omitted from the response when not sent.
      - `longitude` CoordinateInput, required: Flexible coordinate input supporting multiple formats.
        - `components` object: Separate degree components with direction
        - `decimal` number: Decimal degrees (-90 to 90 for lat, -180 to 180 for lon)
        - `dms` string: Degrees, minutes, seconds string (e.g., '40°42'46"N')
      - `region` string: State/region
      - `timezone` TimezoneInput, required: Timezone input using IANA names or UTC offsets.
        - `fold_preference` 'earlier' | 'later': Which occurrence to use when the naive local datetime falls in a fall-back fold (a repeated hour): 'earlier' (default — first occurrence) or 'later'. Only meaningful for naive datetimes; the response reports datetime_status=ambiguous_fold either way so the ambiguity can be surfaced to the user.
        - `iana_name` string: IANA timezone name
        - `time_standard` 'auto' | 'standard' | 'daylight': How to interpret a naive local datetime when this zone is applied. 'auto' (default): resolve through the historical-correction overlay where one covers the region/era, then IANA tzdata. 'standard': force the zone's standard (non-daylight) offset — for callers who KNOW the recorded time was standard time regardless of what tzdata believes. 'daylight': force standard+1h. Forcing either marks the resolution tz_confidence=client_override. Ignored when the datetime carries its own Z/±HH:MM suffix or when utc_offset is used.
        - `utc_offset` number: UTC offset in hours
    - `gender` string: Gender (optional)
    - `name` string, required: Subject name
    - `notes` string: Additional notes
  - `subject_b` SubjectRequest, required: Subject identity and birth data used to compute a chart.
    - `birth_datetime` DateTimeInput, required: Date/time input in ISO-8601, component, or Julian day form. A value that states a clock time must also state its zone, either as a suffix on the string or via the `timezone` field below.
      - `components` object: Date/time components (year, month, day, and optionally hour, minute, second). If hour/minute are present, pass `timezone` alongside them; without it the request is rejected with 400 ambiguous_datetime. Omit the clock entirely and the date resolves to 12:00 UTC.
      - `iso` string: ISO-8601 datetime (supported range 1550–2650 CE, JPL DE440). If it states a clock time it must carry its zone: either a 'Z'/±HH:MM suffix on the string ("1987-07-15T09:01:00-05:00"), or a `timezone` passed alongside it. A zone-less clock time is rejected with 400 ambiguous_datetime — it is not read as UTC. A date-only value ("1987-07-15") has no clock to be ambiguous about and resolves to 12:00 UTC.
      - `julian_day` number, double: Julian Day Number (always UTC-based, so it needs no zone)
      - `timezone` TimezoneInput: Timezone input using IANA names or UTC offsets.
        - `fold_preference` 'earlier' | 'later': Which occurrence to use when the naive local datetime falls in a fall-back fold (a repeated hour): 'earlier' (default — first occurrence) or 'later'. Only meaningful for naive datetimes; the response reports datetime_status=ambiguous_fold either way so the ambiguity can be surfaced to the user.
        - `iana_name` string: IANA timezone name
        - `time_standard` 'auto' | 'standard' | 'daylight': How to interpret a naive local datetime when this zone is applied. 'auto' (default): resolve through the historical-correction overlay where one covers the region/era, then IANA tzdata. 'standard': force the zone's standard (non-daylight) offset — for callers who KNOW the recorded time was standard time regardless of what tzdata believes. 'daylight': force standard+1h. Forcing either marks the resolution tz_confidence=client_override. Ignored when the datetime carries its own Z/±HH:MM suffix or when utc_offset is used.
        - `utc_offset` number: UTC offset in hours
    - `birth_location` BirthLocation, required: Location context for birth data: coordinates plus timezone.
      - `city` string: City name
      - `country` string: Country
      - `elevation` number: Elevation in meters. Accepted and echoed back unchanged; it does not affect planetary positions, which are computed geocentrically. Elevation changes results only where it is taken as the `elev` query parameter: /eclipse/solar/local (local circumstances) and /time/solar-event plus /ephemeris/agro/* (horizon rise/set times).
      - `latitude` CoordinateInput, required: Flexible coordinate input supporting multiple formats.
        - `components` object: Separate degree components with direction
        - `decimal` number: Decimal degrees (-90 to 90 for lat, -180 to 180 for lon)
        - `dms` string: Degrees, minutes, seconds string (e.g., '40°42'46"N')
      - `location_name` string: Birthplace display name (e.g. "Dallas, TX"). Never affects calculations — coordinates and timezone are the only location facts the engine reads. Echoed back verbatim where the response carries an echo block: as subject.location_name on chart routes that echo a subject (natal, draconic, progressed, synastry, natal-transits, overlay, natal/batch items, predictive transit-chart), inside search_summary on /electional/natal-angle-crossings, metadata on /acg/midpoints, and natal on /human-design/transit-chart. Omitted from the response when not sent.
      - `longitude` CoordinateInput, required: Flexible coordinate input supporting multiple formats.
        - `components` object: Separate degree components with direction
        - `decimal` number: Decimal degrees (-90 to 90 for lat, -180 to 180 for lon)
        - `dms` string: Degrees, minutes, seconds string (e.g., '40°42'46"N')
      - `region` string: State/region
      - `timezone` TimezoneInput, required: Timezone input using IANA names or UTC offsets.
        - `fold_preference` 'earlier' | 'later': Which occurrence to use when the naive local datetime falls in a fall-back fold (a repeated hour): 'earlier' (default — first occurrence) or 'later'. Only meaningful for naive datetimes; the response reports datetime_status=ambiguous_fold either way so the ambiguity can be surfaced to the user.
        - `iana_name` string: IANA timezone name
        - `time_standard` 'auto' | 'standard' | 'daylight': How to interpret a naive local datetime when this zone is applied. 'auto' (default): resolve through the historical-correction overlay where one covers the region/era, then IANA tzdata. 'standard': force the zone's standard (non-daylight) offset — for callers who KNOW the recorded time was standard time regardless of what tzdata believes. 'daylight': force standard+1h. Forcing either marks the resolution tz_confidence=client_override. Ignored when the datetime carries its own Z/±HH:MM suffix or when utc_offset is used.
        - `utc_offset` number: UTC offset in hours
    - `gender` string: Gender (optional)
    - `name` string, required: Subject name
    - `notes` string: Additional notes
  - `visual_config` VisualRenderConfig: Optional rendering preferences for inline chart visuals.
    - `format` 'svg' | 'png': Output encoding: "svg" (default) or "png". PNG requires resvg on the server.
    - `layout` 'graph' | 'mandala': Bodygraph composition: "graph" (default) is the classic layout; "mandala" nests the same diagram inside concentric rings. Ignored for wheel renders. Honored on natal and overlay (transit, connection) bodygraph paths.
    - `size` integer: Canvas pixel dimension. Range [200, 4000]. Default 800.
    - `theme` 'light' | 'dark': Colour palette: "light" (default) or "dark".

## Response `200`

Successful Response

- SynastryResponse: Response for synastry calculation.
  - `aspects` AspectResponse[], required: Cross-aspects between A and B
    - `angle` number, required: Aspect angle in degrees
    - `applying` boolean, required: Is aspect applying
    - `aspect` string, required: Aspect name
    - `object1` string, required: First object name
    - `object2` string, required: Second object name
    - `orb` number, required: Orb in degrees
  - `chart_a` NatalChartEnhancedResponse, required: Enhanced natal chart response with additional calculations. Adjusted to match test expectations: aspects as a list, optional aspect_matrix, permissive calculation_metadata, and chart_type echo.
    - `angles` AnglesResponse, required: Chart angles data in response.
      - `ascendant` number, required: Ascendant longitude in degrees
      - `descendant` number, required: Descendant longitude in degrees
      - `imum_coeli` number, required: Imum Coeli longitude in degrees
      - `midheaven` number, required: Midheaven longitude in degrees
    - `arabic_parts` ArabicPartsResponse: Canonical Arabic parts payload for enhanced responses.
      - `arabic_parts` object, required: Arabic parts keyed by registry name
      - `calculation_time_ms` number, required: Computation time in milliseconds
      - `formulas_used` string[], required: Ordered list of formulas executed
      - `hermetic_lot_names` string[]: Sorted subset of arabic part keys that map to canonical Hermetic lots
      - `sect_determination` object, required: Sect analysis metadata used for formula selection
      - `total_parts_calculated` integer, required: Number of parts returned
    - `aspect_matrix` AspectMatrixResponse: Complete aspect matrix for all planetary pairs. Relaxed to allow additional performance fields provided by enhanced calculator.
      - `aspect_counts` object: Count by aspect type
      - `aspects` AspectResponse[]: All aspects found
        - `angle` number, required: Aspect angle in degrees
        - `applying` boolean, required: Is aspect applying
        - `aspect` string, required: Aspect name
        - `object1` string, required: First object name
        - `object2` string, required: Second object name
        - `orb` number, required: Orb in degrees
      - `calculation_time_ms` number: Calculation time in ms
      - `major_aspects` integer: Major aspect count
      - `matrix` object: Matrix format of aspects
      - `minor_aspects` integer: Minor aspect count
      - `orb_config_used` string: Orb configuration used
      - `patterns` AspectPattern[]: Identified aspect patterns
        - `aspects` string[], required: Aspects forming the pattern
        - `complete` boolean, required: Is pattern complete
        - `orb_tolerance` number, required: Maximum orb in pattern
        - `pattern_type` string, required: Pattern type (T-square, Grand Trine, etc.)
        - `planets` string[], required: Planets involved
        - `strength` number, required: Pattern strength (0-1)
      - `total_aspects` integer: Total number of aspects
    - `aspect_patterns` AspectPattern[]: Detected aspect patterns (Grand Trine, T-Square, Yod, Kite, Stellium, Grand Cross)
      - `aspects` string[], required: Aspects forming the pattern
      - `complete` boolean, required: Is pattern complete
      - `orb_tolerance` number, required: Maximum orb in pattern
      - `pattern_type` string, required: Pattern type (T-square, Grand Trine, etc.)
      - `planets` string[], required: Planets involved
      - `strength` number, required: Pattern strength (0-1)
    - `aspects` EnhancedAspectResponse[]: Enhanced aspects list
      - `aspect_quality` string: Quality assessment derived from dignities or contextual analysis
      - `aspect_type` string, required: Aspect type (e.g., Conjunction, Square)
      - `classification` string, required: Aspect classification (major or minor)
      - `dignity_interaction` string: Summary of the essential dignity interaction between the planets
      - `exact_angle` number, required: Exact angle associated with the aspect type
      - `involves_angle` boolean: True when one side of this aspect is a chart angle (Ascendant/Descendant/Midheaven/Imum Coeli) rather than a body. Angle aspects depend on birth location and local sidereal time, so they change under relocation while planet-planet aspects do not — consumers that relocate charts must recompute or relabel these.
      - `is_applying` boolean: True if the aspect is applying, False if separating, None when undetermined
      - `mutual_reception` boolean: Whether the two planets are in mutual reception
      - `orb` number, required: Absolute distance from the exact angle in degrees
      - `orb_allowance` number: Maximum allowed orb for this aspect and planet pair in degrees
      - `orb_percentage` number, required: Percentage of the allowed orb that is used (0-100)
      - `phase_angle` number, required: Current angular separation between the bodies in degrees
      - `planet1` string, required: First planet involved in the aspect
      - `planet2` string, required: Second planet involved in the aspect
      - `speed_ratio` number: Ratio of the slower planet's absolute speed to the faster one's (0-1)
      - `strength` number, required: Aspect strength scaled between 0.0 and 1.0
    - `calculation_metadata` CalculationMetadata, required: Metadata about chart calculations. Relaxed to allow minimal fields used by tests while remaining forward-compatible.
      - `ascendant_on_left` boolean, nullable: When true (default), the Ascendant is placed at the 9 o'clock (West/left) position � matching the convention used by Astro.com, Solar Fire, and all major astrology software. Set to false to use the ecliptic-fixed (Aries-pinned) orientation instead.
      - `ayanamsa` union: Sidereal ayanamsa selection
        - 'lahiri' | 'fagan_bradley' | 'krishnamurti' | 'raman' | 'yukteshwar': Supported sidereal ayanamsa options. All five are computed from the same IAU 2006 general-precession model, so each is epoch-dependent rather than a frozen constant; they differ by up to ~2.3 degrees, which is enough to move a body across a sign boundary. Defaults to lahiri when zodiac_type is sidereal and no system is named.
        - string
      - `calculation_time` number: Legacy calculation time in seconds
      - `calculation_time_ms` number: Processing time at the orchestrator layer in milliseconds
      - `calculation_time_utc` string, date-time: UTC timestamp when the calculation executed
      - `coordinate_reference_frame` string: Coordinate frame the positions are expressed in. The engine computes apparent places referred to the true equator/equinox of date and converts them to the true ecliptic of date, so this reads geocentric_true_ecliptic_of_date.
      - `coordinate_system` union: Coordinate system used (geocentric/topocentric)
        - 'geocentric' | 'topocentric' | 'heliocentric' | 'barycentric': Coordinate system used for calculations.
        - string
      - `delta_t_seconds` number: Delta T (TT - UT1) applied during calculation, in seconds
      - `delta_t_source` union: Source of Delta T values (computation engine, IERS, approximation)
        - 'nasa_jpl' | 'iers' | 'approximation_model': Source of ΔT values used in calculations.
        - string
      - `ephemeris_source` string: Primary ephemeris source (e.g., SuperNOVAS / Calceph)
      - `ephemeris_version` string: Version of the ephemeris data files
      - `fixed_star_catalog` union: Fixed star catalog or subset identifier
        - 'bright_mag3' | 'bright_mag5' | 'royal_stars' | 'parans_key': Fixed star catalog snapshots.
        - string
      - `house_system` union: House system actually used during calculation
        - 'P' | 'K' | 'O' | 'R' | 'C' | 'E' | 'W': Supported house systems.
        - string
      - `include_fixed_stars` boolean: Whether fixed stars were included
      - `julian_day` number, double: Julian Day Number representing the calculation instant
      - `missing_objects` object: Objects that could not be calculated along with reasons
      - `node_source` union: Lunar node/apsides mode requested (true osculating, mean, apsides)
        - 'true_osculating' | 'mean' | 'mean_apsides': Node/apsides calculation modes (SE §2.2).
        - string
      - `object_set` union: Named object set or preset powering the calculation
        - 'traditional_7' | 'modern_10' | 'modern_plus_chiron' | 'asteroids_major' | 'full' | 'custom': Standardized celestial object bundles.
        - string
      - `orb_system_used` string: Aspect orb system applied
      - `precision_level` string: Legacy precision descriptor
      - `precision_summary` PrecisionSummary: Structured precision report for calculation metadata.
        - `max_position_error_arcseconds` number: Maximum validated positional error in arcseconds
        - `max_timing_error_seconds` number: Maximum validated timing error in seconds
        - `notes` string: Additional human-readable context for the precision summary
        - `reference_profile` string: Reference dataset or validation profile used for the comparison
      - `processing_time_ms` number: End-to-end processing time in milliseconds
      - `server_version` string: Build identifier of the engine that produced this response. Moves on every deploy, so it is the signal for resolution-LOGIC changes — the class of change that can move a historical offset without touching overlay data (and therefore without moving tz_overlay_version). Poll both.
      - `sidereal_time` number: Local sidereal time in hours
      - `technique_id` string: High-level technique identifier (e.g., natal, synastry, composite, overlay)
      - `technique_label` string: Human-readable technique label
      - `technique_method` string: Method name within a technique (e.g., davidson, midpoint)
      - `technique_version` string: Technique implementation version (for future-proofing)
      - `time_scale` union: Time scale used for internal calculations (UTC, TT, TDB)
        - 'UTC' | 'TT' | 'TDB': Time scale used for reporting results.
        - string
      - `tz_overlay_hash` string: Content hash of the historical-correction overlay dataset that produced this answer. Stamped only when an overlay row applied (tz_rule_source starts with 'overlay:').
      - `tz_overlay_version` integer: Monotonic version of the historical-correction overlay dataset that produced this answer. Stamped only when an overlay row applied. Tracks overlay DATA only — pair with server_version to also catch resolution-logic changes.
      - `tz_precision` 'statutory' | 'documented' | 'inferred': Sourcing grade of the overlay row that produced the offset: 'statutory' (operative text of a session law or statute verified), 'documented' (contemporary reporting), or 'inferred' (deduced from legal context; verify before relying on it near the row's edges). Stamped only when an overlay row applied.
      - `tz_rule_citation` string: Primary-source citation for the overlay row that produced the offset — statute reference, ICC/agency order number, or documented press/almanac source. Stamped only when an overlay row applied.
      - `zodiac_type` union: Zodiac framework applied (tropical/sidereal)
        - 'tropical' | 'sidereal': Supported zodiac frameworks.
        - string
    - `chart_type` string: Chart type identifier
    - `declination_aspects` DeclinationAspect[]: Declination-based aspects
      - `applying` boolean, required: Whether aspect is applying
      - `body1` string, required: First body name
      - `body2` string, required: Second body name
      - `declination1` number, required: First body declination
      - `declination2` number, required: Second body declination
      - `orb` number, required: Orb difference in degrees
      - `type` string, required: Aspect type
    - `element_balance` object: Elemental balance
    - `elongations` object: Sun-relative elongations (per-body separation and signed east/west delta) (opt-in).
    - `fixed_stars` FixedStarsResponse: Container for fixed star positions and conjunctions.
      - `conjunctions` FixedStarConjunctionResponse[], required: Star-planet conjunctions
        - `exact` boolean, required: Whether orb is below exact threshold
        - `interpretation_hint` string: Quick interpretation keyword
        - `orb` number, required: Orb in degrees
        - `planet` string, required: Planet name
        - `planet_longitude` number, required: Planet longitude in degrees
        - `star` string, required: Fixed star name
        - `star_longitude` number, required: Star longitude in degrees
      - `metadata` FixedStarsMetadata, required: Metadata describing fixed star calculation.
        - `available_catalog` boolean, required: Whether built-in star catalog was available
        - `calculation_duration_ms` number: Computation time in milliseconds
        - `calculation_time` string: ISO8601 timestamp of calculation
        - `error` string: Optional error description if calculation degraded
        - `magnitude_limit` number: Magnitude limit applied
        - `missing_stars` string[]: Stars requested but unavailable
        - `orb_used` number: Orb used for conjunction detection
        - `requested_star_count` integer, required: Number of stars requested
        - `selected_stars_count` integer, required: Count of Foundation 24 stars returned
        - `total_stars_calculated` integer, required: Number of stars calculated
      - `positions` FixedStarPositionResponse[], required: Calculated star positions
        - `constellation` string: Constellation
        - `distance_light_years` number: Distance in light years
        - `julian_day` number, double: Julian Day of calculation
        - `latitude` number, required: Latitude in degrees
        - `longitude` number, required: Current longitude in degrees
        - `magnitude` number: Apparent magnitude
        - `name` string, required: Fixed star name
        - `sign_longitude` number: Longitude within sign
        - `sign_name` string: Zodiac sign
        - `sign_symbol` string: Zodiac sign symbol
        - `spectral_class` string: Spectral classification
        - `traditional_name` string: Traditional name
    - `harmonics` object: Harmonic chart positions keyed by harmonic number
    - `hemisphere_emphasis` object: Hemisphere weights
    - `houses` HousesResponse, required: House system data in response.
      - `cusps` number[], required: House cusp longitudes in degrees
      - `system` string, required: House system code
    - `human_design_gates` object: Human Design / I Ching gate + line mappings from ecliptic longitude (math-only; includes mapping version) (opt-in).
    - `lunar_phase` object: Lunar phase context (phase name, illumination, phase angle, waxing/waning, days-to-new/full) (opt-in).
    - `midpoints` object[]: Calculated midpoints between planet pairs
    - `omitted_bodies` OmittedBody[], nullable: Bodies that were requested (or are in the chosen object_set/asteroid_groups) but not computed because the chart date is outside the span of their own JPL kernel. Absent when nothing was omitted. Each entry carries the body's valid_from/valid_to. Applies to the bodies that have a per-body kernel (the centaurs, trans-Neptunian objects and extended asteroids: 1600-2200 CE); the planets, nodes and sb441 main-belt asteroids cover 1550-2650 and a date outside that is rejected outright.
      - `detail` string: Human-readable explanation.
      - `id` string, required: Canonical body id (see GET /catalogs/bodies).
      - `name` string, required: Body name.
      - `reason` string, required: Why it was omitted. `outside_kernel_window`: the instant is outside the span of this body's own JPL kernel (valid_from..valid_to). Only bodies with a per-body kernel (the centaurs, trans-Neptunian objects and extended asteroids) have such a window; the planets, nodes and the sb441 main-belt asteroids cover the full 1550-2650 range.
      - `valid_from` string: First date the body is computed (YYYY-MM-DD).
      - `valid_to` string: Last date the body is computed (YYYY-MM-DD).
    - `patterns_by_type` object: Patterns organized by type for easier filtering
    - `planets` object, required: Planetary positions keyed by name
    - `sect_determination` SectDeterminationResponse: Sect determination analysis.
      - `benefics_in_sect` string[], required: Benefics in proper sect
      - `is_day_chart` boolean, required: Is this a day chart
      - `malefics_in_sect` string[], required: Malefics in proper sect
      - `sect` string, required: Chart sect (diurnal/nocturnal)
      - `sect_conditions` object, required: Detailed sect conditions
      - `sect_light` string, required: Sect light (Sun for day, Moon for night)
      - `sun_above_horizon` boolean, required: Is Sun above horizon
    - `solar_relationships` object: Solar relationship / visibility classifications (e.g., cazimi/combust/under-beams) and Mercury/Venus morning/evening star context.
    - `subject` SubjectResponse, required: Normalized subject data in response.
      - `altitude` number, required: Altitude in meters
      - `datetime` string, required: ISO format datetime
      - `julian_day` number, double, required: Julian Day Number
      - `latitude` number, required: Latitude in decimal degrees
      - `longitude` number, required: Longitude in decimal degrees
      - `name` string, required: Subject name
      - `timezone_name` string: Timezone name if available
      - `utc_offset` number: UTC offset in hours
    - `success` boolean: Response success status
    - `visual` VisualResult: Embedded diagram payload returned alongside chart data when include_visual=true.
      - `content_type` string, required: MIME type of the data payload.
      - `credits_charged` integer, required: Additional credits consumed to render the visual: 2, or 0 on a re-render that presented a valid render_token.
      - `data` string, required: Raw SVG string (format=svg) or standard base64-encoded PNG bytes (format=png, no data: URI prefix).
      - `format` string, required: Output format: "svg" or "png".
      - `render_token` string: Short-lived (15 min) token for re-rendering this same chart. Send it back in the X-OE-Render-Token header (or a top-level render_token body field) with a request for the same chart inputs — e.g. the same birth data in a different theme or layout — and that request is not charged again. Bound to your account and to the chart-defining inputs; any other request is charged normally.
      - `type` string, required: Diagram kind: "wheel" or "bodygraph".
    - `void_of_course` object: Void-of-Course Moon context (status, start/end window, last major aspect, sign context) (opt-in).
  - `chart_b` NatalChartEnhancedResponse, required: Enhanced natal chart response with additional calculations. Adjusted to match test expectations: aspects as a list, optional aspect_matrix, permissive calculation_metadata, and chart_type echo.
    - `angles` AnglesResponse, required: Chart angles data in response.
      - `ascendant` number, required: Ascendant longitude in degrees
      - `descendant` number, required: Descendant longitude in degrees
      - `imum_coeli` number, required: Imum Coeli longitude in degrees
      - `midheaven` number, required: Midheaven longitude in degrees
    - `arabic_parts` ArabicPartsResponse: Canonical Arabic parts payload for enhanced responses.
      - `arabic_parts` object, required: Arabic parts keyed by registry name
      - `calculation_time_ms` number, required: Computation time in milliseconds
      - `formulas_used` string[], required: Ordered list of formulas executed
      - `hermetic_lot_names` string[]: Sorted subset of arabic part keys that map to canonical Hermetic lots
      - `sect_determination` object, required: Sect analysis metadata used for formula selection
      - `total_parts_calculated` integer, required: Number of parts returned
    - `aspect_matrix` AspectMatrixResponse: Complete aspect matrix for all planetary pairs. Relaxed to allow additional performance fields provided by enhanced calculator.
      - `aspect_counts` object: Count by aspect type
      - `aspects` AspectResponse[]: All aspects found
        - `angle` number, required: Aspect angle in degrees
        - `applying` boolean, required: Is aspect applying
        - `aspect` string, required: Aspect name
        - `object1` string, required: First object name
        - `object2` string, required: Second object name
        - `orb` number, required: Orb in degrees
      - `calculation_time_ms` number: Calculation time in ms
      - `major_aspects` integer: Major aspect count
      - `matrix` object: Matrix format of aspects
      - `minor_aspects` integer: Minor aspect count
      - `orb_config_used` string: Orb configuration used
      - `patterns` AspectPattern[]: Identified aspect patterns
        - `aspects` string[], required: Aspects forming the pattern
        - `complete` boolean, required: Is pattern complete
        - `orb_tolerance` number, required: Maximum orb in pattern
        - `pattern_type` string, required: Pattern type (T-square, Grand Trine, etc.)
        - `planets` string[], required: Planets involved
        - `strength` number, required: Pattern strength (0-1)
      - `total_aspects` integer: Total number of aspects
    - `aspect_patterns` AspectPattern[]: Detected aspect patterns (Grand Trine, T-Square, Yod, Kite, Stellium, Grand Cross)
      - `aspects` string[], required: Aspects forming the pattern
      - `complete` boolean, required: Is pattern complete
      - `orb_tolerance` number, required: Maximum orb in pattern
      - `pattern_type` string, required: Pattern type (T-square, Grand Trine, etc.)
      - `planets` string[], required: Planets involved
      - `strength` number, required: Pattern strength (0-1)
    - `aspects` EnhancedAspectResponse[]: Enhanced aspects list
      - `aspect_quality` string: Quality assessment derived from dignities or contextual analysis
      - `aspect_type` string, required: Aspect type (e.g., Conjunction, Square)
      - `classification` string, required: Aspect classification (major or minor)
      - `dignity_interaction` string: Summary of the essential dignity interaction between the planets
      - `exact_angle` number, required: Exact angle associated with the aspect type
      - `involves_angle` boolean: True when one side of this aspect is a chart angle (Ascendant/Descendant/Midheaven/Imum Coeli) rather than a body. Angle aspects depend on birth location and local sidereal time, so they change under relocation while planet-planet aspects do not — consumers that relocate charts must recompute or relabel these.
      - `is_applying` boolean: True if the aspect is applying, False if separating, None when undetermined
      - `mutual_reception` boolean: Whether the two planets are in mutual reception
      - `orb` number, required: Absolute distance from the exact angle in degrees
      - `orb_allowance` number: Maximum allowed orb for this aspect and planet pair in degrees
      - `orb_percentage` number, required: Percentage of the allowed orb that is used (0-100)
      - `phase_angle` number, required: Current angular separation between the bodies in degrees
      - `planet1` string, required: First planet involved in the aspect
      - `planet2` string, required: Second planet involved in the aspect
      - `speed_ratio` number: Ratio of the slower planet's absolute speed to the faster one's (0-1)
      - `strength` number, required: Aspect strength scaled between 0.0 and 1.0
    - `calculation_metadata` CalculationMetadata, required: Metadata about chart calculations. Relaxed to allow minimal fields used by tests while remaining forward-compatible.
      - `ascendant_on_left` boolean, nullable: When true (default), the Ascendant is placed at the 9 o'clock (West/left) position � matching the convention used by Astro.com, Solar Fire, and all major astrology software. Set to false to use the ecliptic-fixed (Aries-pinned) orientation instead.
      - `ayanamsa` union: Sidereal ayanamsa selection
        - 'lahiri' | 'fagan_bradley' | 'krishnamurti' | 'raman' | 'yukteshwar': Supported sidereal ayanamsa options. All five are computed from the same IAU 2006 general-precession model, so each is epoch-dependent rather than a frozen constant; they differ by up to ~2.3 degrees, which is enough to move a body across a sign boundary. Defaults to lahiri when zodiac_type is sidereal and no system is named.
        - string
      - `calculation_time` number: Legacy calculation time in seconds
      - `calculation_time_ms` number: Processing time at the orchestrator layer in milliseconds
      - `calculation_time_utc` string, date-time: UTC timestamp when the calculation executed
      - `coordinate_reference_frame` string: Coordinate frame the positions are expressed in. The engine computes apparent places referred to the true equator/equinox of date and converts them to the true ecliptic of date, so this reads geocentric_true_ecliptic_of_date.
      - `coordinate_system` union: Coordinate system used (geocentric/topocentric)
        - 'geocentric' | 'topocentric' | 'heliocentric' | 'barycentric': Coordinate system used for calculations.
        - string
      - `delta_t_seconds` number: Delta T (TT - UT1) applied during calculation, in seconds
      - `delta_t_source` union: Source of Delta T values (computation engine, IERS, approximation)
        - 'nasa_jpl' | 'iers' | 'approximation_model': Source of ΔT values used in calculations.
        - string
      - `ephemeris_source` string: Primary ephemeris source (e.g., SuperNOVAS / Calceph)
      - `ephemeris_version` string: Version of the ephemeris data files
      - `fixed_star_catalog` union: Fixed star catalog or subset identifier
        - 'bright_mag3' | 'bright_mag5' | 'royal_stars' | 'parans_key': Fixed star catalog snapshots.
        - string
      - `house_system` union: House system actually used during calculation
        - 'P' | 'K' | 'O' | 'R' | 'C' | 'E' | 'W': Supported house systems.
        - string
      - `include_fixed_stars` boolean: Whether fixed stars were included
      - `julian_day` number, double: Julian Day Number representing the calculation instant
      - `missing_objects` object: Objects that could not be calculated along with reasons
      - `node_source` union: Lunar node/apsides mode requested (true osculating, mean, apsides)
        - 'true_osculating' | 'mean' | 'mean_apsides': Node/apsides calculation modes (SE §2.2).
        - string
      - `object_set` union: Named object set or preset powering the calculation
        - 'traditional_7' | 'modern_10' | 'modern_plus_chiron' | 'asteroids_major' | 'full' | 'custom': Standardized celestial object bundles.
        - string
      - `orb_system_used` string: Aspect orb system applied
      - `precision_level` string: Legacy precision descriptor
      - `precision_summary` PrecisionSummary: Structured precision report for calculation metadata.
        - `max_position_error_arcseconds` number: Maximum validated positional error in arcseconds
        - `max_timing_error_seconds` number: Maximum validated timing error in seconds
        - `notes` string: Additional human-readable context for the precision summary
        - `reference_profile` string: Reference dataset or validation profile used for the comparison
      - `processing_time_ms` number: End-to-end processing time in milliseconds
      - `server_version` string: Build identifier of the engine that produced this response. Moves on every deploy, so it is the signal for resolution-LOGIC changes — the class of change that can move a historical offset without touching overlay data (and therefore without moving tz_overlay_version). Poll both.
      - `sidereal_time` number: Local sidereal time in hours
      - `technique_id` string: High-level technique identifier (e.g., natal, synastry, composite, overlay)
      - `technique_label` string: Human-readable technique label
      - `technique_method` string: Method name within a technique (e.g., davidson, midpoint)
      - `technique_version` string: Technique implementation version (for future-proofing)
      - `time_scale` union: Time scale used for internal calculations (UTC, TT, TDB)
        - 'UTC' | 'TT' | 'TDB': Time scale used for reporting results.
        - string
      - `tz_overlay_hash` string: Content hash of the historical-correction overlay dataset that produced this answer. Stamped only when an overlay row applied (tz_rule_source starts with 'overlay:').
      - `tz_overlay_version` integer: Monotonic version of the historical-correction overlay dataset that produced this answer. Stamped only when an overlay row applied. Tracks overlay DATA only — pair with server_version to also catch resolution-logic changes.
      - `tz_precision` 'statutory' | 'documented' | 'inferred': Sourcing grade of the overlay row that produced the offset: 'statutory' (operative text of a session law or statute verified), 'documented' (contemporary reporting), or 'inferred' (deduced from legal context; verify before relying on it near the row's edges). Stamped only when an overlay row applied.
      - `tz_rule_citation` string: Primary-source citation for the overlay row that produced the offset — statute reference, ICC/agency order number, or documented press/almanac source. Stamped only when an overlay row applied.
      - `zodiac_type` union: Zodiac framework applied (tropical/sidereal)
        - 'tropical' | 'sidereal': Supported zodiac frameworks.
        - string
    - `chart_type` string: Chart type identifier
    - `declination_aspects` DeclinationAspect[]: Declination-based aspects
      - `applying` boolean, required: Whether aspect is applying
      - `body1` string, required: First body name
      - `body2` string, required: Second body name
      - `declination1` number, required: First body declination
      - `declination2` number, required: Second body declination
      - `orb` number, required: Orb difference in degrees
      - `type` string, required: Aspect type
    - `element_balance` object: Elemental balance
    - `elongations` object: Sun-relative elongations (per-body separation and signed east/west delta) (opt-in).
    - `fixed_stars` FixedStarsResponse: Container for fixed star positions and conjunctions.
      - `conjunctions` FixedStarConjunctionResponse[], required: Star-planet conjunctions
        - `exact` boolean, required: Whether orb is below exact threshold
        - `interpretation_hint` string: Quick interpretation keyword
        - `orb` number, required: Orb in degrees
        - `planet` string, required: Planet name
        - `planet_longitude` number, required: Planet longitude in degrees
        - `star` string, required: Fixed star name
        - `star_longitude` number, required: Star longitude in degrees
      - `metadata` FixedStarsMetadata, required: Metadata describing fixed star calculation.
        - `available_catalog` boolean, required: Whether built-in star catalog was available
        - `calculation_duration_ms` number: Computation time in milliseconds
        - `calculation_time` string: ISO8601 timestamp of calculation
        - `error` string: Optional error description if calculation degraded
        - `magnitude_limit` number: Magnitude limit applied
        - `missing_stars` string[]: Stars requested but unavailable
        - `orb_used` number: Orb used for conjunction detection
        - `requested_star_count` integer, required: Number of stars requested
        - `selected_stars_count` integer, required: Count of Foundation 24 stars returned
        - `total_stars_calculated` integer, required: Number of stars calculated
      - `positions` FixedStarPositionResponse[], required: Calculated star positions
        - `constellation` string: Constellation
        - `distance_light_years` number: Distance in light years
        - `julian_day` number, double: Julian Day of calculation
        - `latitude` number, required: Latitude in degrees
        - `longitude` number, required: Current longitude in degrees
        - `magnitude` number: Apparent magnitude
        - `name` string, required: Fixed star name
        - `sign_longitude` number: Longitude within sign
        - `sign_name` string: Zodiac sign
        - `sign_symbol` string: Zodiac sign symbol
        - `spectral_class` string: Spectral classification
        - `traditional_name` string: Traditional name
    - `harmonics` object: Harmonic chart positions keyed by harmonic number
    - `hemisphere_emphasis` object: Hemisphere weights
    - `houses` HousesResponse, required: House system data in response.
      - `cusps` number[], required: House cusp longitudes in degrees
      - `system` string, required: House system code
    - `human_design_gates` object: Human Design / I Ching gate + line mappings from ecliptic longitude (math-only; includes mapping version) (opt-in).
    - `lunar_phase` object: Lunar phase context (phase name, illumination, phase angle, waxing/waning, days-to-new/full) (opt-in).
    - `midpoints` object[]: Calculated midpoints between planet pairs
    - `omitted_bodies` OmittedBody[], nullable: Bodies that were requested (or are in the chosen object_set/asteroid_groups) but not computed because the chart date is outside the span of their own JPL kernel. Absent when nothing was omitted. Each entry carries the body's valid_from/valid_to. Applies to the bodies that have a per-body kernel (the centaurs, trans-Neptunian objects and extended asteroids: 1600-2200 CE); the planets, nodes and sb441 main-belt asteroids cover 1550-2650 and a date outside that is rejected outright.
      - `detail` string: Human-readable explanation.
      - `id` string, required: Canonical body id (see GET /catalogs/bodies).
      - `name` string, required: Body name.
      - `reason` string, required: Why it was omitted. `outside_kernel_window`: the instant is outside the span of this body's own JPL kernel (valid_from..valid_to). Only bodies with a per-body kernel (the centaurs, trans-Neptunian objects and extended asteroids) have such a window; the planets, nodes and the sb441 main-belt asteroids cover the full 1550-2650 range.
      - `valid_from` string: First date the body is computed (YYYY-MM-DD).
      - `valid_to` string: Last date the body is computed (YYYY-MM-DD).
    - `patterns_by_type` object: Patterns organized by type for easier filtering
    - `planets` object, required: Planetary positions keyed by name
    - `sect_determination` SectDeterminationResponse: Sect determination analysis.
      - `benefics_in_sect` string[], required: Benefics in proper sect
      - `is_day_chart` boolean, required: Is this a day chart
      - `malefics_in_sect` string[], required: Malefics in proper sect
      - `sect` string, required: Chart sect (diurnal/nocturnal)
      - `sect_conditions` object, required: Detailed sect conditions
      - `sect_light` string, required: Sect light (Sun for day, Moon for night)
      - `sun_above_horizon` boolean, required: Is Sun above horizon
    - `solar_relationships` object: Solar relationship / visibility classifications (e.g., cazimi/combust/under-beams) and Mercury/Venus morning/evening star context.
    - `subject` SubjectResponse, required: Normalized subject data in response.
      - `altitude` number, required: Altitude in meters
      - `datetime` string, required: ISO format datetime
      - `julian_day` number, double, required: Julian Day Number
      - `latitude` number, required: Latitude in decimal degrees
      - `longitude` number, required: Longitude in decimal degrees
      - `name` string, required: Subject name
      - `timezone_name` string: Timezone name if available
      - `utc_offset` number: UTC offset in hours
    - `success` boolean: Response success status
    - `visual` VisualResult: Embedded diagram payload returned alongside chart data when include_visual=true.
      - `content_type` string, required: MIME type of the data payload.
      - `credits_charged` integer, required: Additional credits consumed to render the visual: 2, or 0 on a re-render that presented a valid render_token.
      - `data` string, required: Raw SVG string (format=svg) or standard base64-encoded PNG bytes (format=png, no data: URI prefix).
      - `format` string, required: Output format: "svg" or "png".
      - `render_token` string: Short-lived (15 min) token for re-rendering this same chart. Send it back in the X-OE-Render-Token header (or a top-level render_token body field) with a request for the same chart inputs — e.g. the same birth data in a different theme or layout — and that request is not charged again. Bound to your account and to the chart-defining inputs; any other request is charged normally.
      - `type` string, required: Diagram kind: "wheel" or "bodygraph".
    - `void_of_course` object: Void-of-Course Moon context (status, start/end window, last major aspect, sign context) (opt-in).
  - `visual` VisualResult: Embedded diagram payload returned alongside chart data when include_visual=true.
    - `content_type` string, required: MIME type of the data payload.
    - `credits_charged` integer, required: Additional credits consumed to render the visual: 2, or 0 on a re-render that presented a valid render_token.
    - `data` string, required: Raw SVG string (format=svg) or standard base64-encoded PNG bytes (format=png, no data: URI prefix).
    - `format` string, required: Output format: "svg" or "png".
    - `render_token` string: Short-lived (15 min) token for re-rendering this same chart. Send it back in the X-OE-Render-Token header (or a top-level render_token body field) with a request for the same chart inputs — e.g. the same birth data in a different theme or layout — and that request is not charged again. Bound to your account and to the chart-defining inputs; any other request is charged normally.
    - `type` string, required: Diagram kind: "wheel" or "bodygraph".

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/openephemeris/apis/open-ephemeris-api.md) · [All operations](https://skmtc.dev/openephemeris/apis/open-ephemeris-api/llms.txt) · [OpenAPI document](https://skmtc.dev/openephemeris/apis/open-ephemeris-api/revisions/d195a769cb89?raw)
