Morphemeris DocsBeta

Transit Scan

GET /v1/transits — Find every aspect window between moving bodies and a natal chart (or each other) over a date range.

Transit Scan

Scan a date range for aspect windows: the periods when a moving body is within orb of an aspect to a natal chart's points, or, with targets=mutual, to the other moving bodies. Each event is one contiguous in-orb window with the instant the pair came within orb, every exact contact inside it, and the instant it left. A retrograde loop that perfects three times without leaving orb is one event with three exacts, not three events.

This is the endpoint a dynamic report or a time map is built from. It replaces the daily-position polling described in the transits guide.

Text
GET  /v1/transits
POST /v1/transits

Credit cost: 5

Parameters

ParameterTypeRequiredDefaultDescription
startstringOne of start or start_jdRange start, ISO 8601 UTC
start_jdnumberOne of start or start_jdRange start as a Julian Day (UT1)
endstringOne of end or end_jdRange end. After start, at most 366 days later (183 with moon=include)
end_jdnumberOne of end or end_jdRange end as a Julian Day (UT1)
targetsstringNonatalnatal: a chart's bodies, plus its Ascendant and Midheaven when lat/lon are given. mutual: the moving bodies against each other, each unordered pair once
datetimestringFor natalNatal moment, ISO 8601 UTC (or jd). Not accepted with targets=mutual
jdnumberFor natalNatal moment as a Julian Day (UT1)
lat, lonnumberNoNatal location. Adds the natal Ascendant and Midheaven as targets
bodiesstringNoplanetsNatal points to scan against: body names, or planets, asteroids, all
movingstringNoSun through PlutoComma-separated moving bodies. Planets, mean_node, true_node, chiron, ceres, pallas, juno, vesta
aspectsstringNomajor fiveComma-separated aspects (conjunction, sextile, square, trine, opposition, quincunx, …)
orbnumberNo1.0One flat orb in degrees for every aspect and pair, 0 < orb ≤ 10. Transit practice uses a tight, flat orb
moonstringNoreturns_onlySee below

The Moon. It aspects every point in a chart every month, so on any range longer than a few weeks its events bury everything else, and it is sampled about fifty times a day. The default, returns_only, scans it normally on ranges under 14 days and beyond that keeps only its conjunction to natal moon (the lunar return), adding a warning that says which pairs were dropped. include scans it like any other body and limits the range to 183 days. exclude drops it.

No calculation flags. An aspect is a difference between two longitudes, so a zodiac rotation cancels out of every event: a sidereal scan would find exactly the same windows. Passing sidereal (or any other flag) returns 400.

Range. At most a year (366 days) per request, half a year with moon=include. A default year (the ten planets against twelve natal points, the major five aspects) takes a few seconds; the widest shapes a year admits, all fifteen aspects with bodies=all or targets=mutual, about 18 s. For longer spans, send several ranges in one batch call and join the windows that are clamped at a shared boundary.

Response

JSON
{
  "data": {
    "targets": "natal",
    "start": { "jd": 2461041.5, "datetime": "2026-01-01T00:00:00.000Z" },
    "end": { "jd": 2461100.5, "datetime": "2026-03-01T00:00:00.000Z" },
    "points": [
      { "body": "sun", "longitude": 84.2 },
      { "body": "ascendant", "longitude": 201.7 }
    ],
    "moving": ["sun", "moon", "mercury", "venus", "mars", "jupiter", "saturn", "uranus", "neptune", "pluto"],
    "aspects": ["conjunction", "sextile", "square", "trine", "opposition"],
    "orb": 1.0,
    "events": [
      {
        "moving": "mars",
        "aspect": "conjunction",
        "target": "neptune",
        "enter": { "jd": 2461041.534, "datetime": "2026-01-01T00:49:26.012Z" },
        "exacts": [{ "jd": 2461042.838, "datetime": "2026-01-02T08:07:18.893Z" }],
        "leave": { "jd": 2461044.141, "datetime": "2026-01-03T15:23:05.777Z" },
        "clamped_start": false,
        "clamped_end": false
      }
    ]
  },
  "meta": { "..." },
  "warnings": ["low precision: moon policy dropped 12 body pairs from a 59-day scan; pass moon=include to keep them"]
}
FieldTypeDescription
targetsstringnatal or mutual
start, endinstantThe range scanned, as { jd, datetime }
pointsarrayThe natal points scanned against, with the longitudes used. Absent for mutual
moving, aspects, orbThe configuration the scan ran with
events[].movingstringThe moving body
events[].aspectstringThe aspect
events[].targetstringThe point aspected: a natal body, ascendant, midheaven, or for mutual another moving body
events[].enterinstantWhen the pair came within orb
events[].exactsinstant[]Exact contacts, ascending. Empty for a window that never perfects: a body that turns retrograde inside the orb and withdraws
events[].leaveinstantWhen the pair left orb
events[].clamped_startbooleanenter is the range start, not a real ingress: the pair was already in orb
events[].clamped_endbooleanleave is the range end, not a real egress

Events are ordered by enter, then moving, then target. Every instant is UT1 rendered through the leap-second table, to the millisecond.

Examples

Two months of transits to a natal chart

Bash
curl "https://api.morphemeris.com/v1/transits?datetime=1990-06-15T14:30:00Z&lat=40.7&lon=-74&start=2026-01-01T00:00:00Z&end=2026-03-01T00:00:00Z" \
  -H "Authorization: Bearer morphemeris_live_YOUR_KEY"
javascript
const res = await fetch(
  "https://api.morphemeris.com/v1/transits?datetime=1990-06-15T14:30:00Z&lat=40.7&lon=-74&start=2026-01-01T00:00:00Z&end=2026-03-01T00:00:00Z",
  { headers: { Authorization: "Bearer morphemeris_live_YOUR_KEY" } }
);
const { data, warnings } = await res.json();
Python
import requests

res = requests.get(
    "https://api.morphemeris.com/v1/transits",
    params={
        "datetime": "1990-06-15T14:30:00Z", "lat": 40.7, "lon": -74,
        "start": "2026-01-01T00:00:00Z", "end": "2026-03-01T00:00:00Z",
    },
    headers={"Authorization": "Bearer morphemeris_live_YOUR_KEY"},
)
data = res.json()

Outer planets only, tighter orb

Bash
curl "https://api.morphemeris.com/v1/transits?datetime=1990-06-15T14:30:00Z&moving=jupiter,saturn,uranus,neptune,pluto&orb=0.5&start=2026-01-01T00:00:00Z&end=2026-03-01T00:00:00Z" \
  -H "Authorization: Bearer morphemeris_live_YOUR_KEY"

Mundane transits: the moving bodies against each other

Bash
curl "https://api.morphemeris.com/v1/transits?targets=mutual&moving=sun,mars,jupiter,saturn&start=2026-01-01T00:00:00Z&end=2026-03-01T00:00:00Z" \
  -H "Authorization: Bearer morphemeris_live_YOUR_KEY"

A year, in one batch call

Bash
curl -X POST "https://api.morphemeris.com/v1/batch" \
  -H "Authorization: Bearer morphemeris_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"requests": [
    {"endpoint": "/v1/transits", "params": {"datetime": "1990-06-15T14:30:00Z", "lat": 40.7, "lon": -74, "start": "2026-01-01T00:00:00Z", "end": "2027-01-01T00:00:00Z"}},
    {"endpoint": "/v1/transits", "params": {"datetime": "1990-06-15T14:30:00Z", "lat": 40.7, "lon": -74, "start": "2027-01-01T00:00:00Z", "end": "2028-01-01T00:00:00Z"}}
  ]}'

See also Planetary Returns for the full chart at a return moment, and Sign Ingresses for sign boundaries.