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.
GET /v1/transits
POST /v1/transitsCredit cost: 5
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
start | string | One of start or start_jd | — | Range start, ISO 8601 UTC |
start_jd | number | One of start or start_jd | — | Range start as a Julian Day (UT1) |
end | string | One of end or end_jd | — | Range end. After start, at most 366 days later (183 with moon=include) |
end_jd | number | One of end or end_jd | — | Range end as a Julian Day (UT1) |
targets | string | No | natal | natal: 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 |
datetime | string | For natal | — | Natal moment, ISO 8601 UTC (or jd). Not accepted with targets=mutual |
jd | number | For natal | — | Natal moment as a Julian Day (UT1) |
lat, lon | number | No | — | Natal location. Adds the natal Ascendant and Midheaven as targets |
bodies | string | No | planets | Natal points to scan against: body names, or planets, asteroids, all |
moving | string | No | Sun through Pluto | Comma-separated moving bodies. Planets, mean_node, true_node, chiron, ceres, pallas, juno, vesta |
aspects | string | No | major five | Comma-separated aspects (conjunction, sextile, square, trine, opposition, quincunx, …) |
orb | number | No | 1.0 | One flat orb in degrees for every aspect and pair, 0 < orb ≤ 10. Transit practice uses a tight, flat orb |
moon | string | No | returns_only | See 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
{
"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"]
}| Field | Type | Description |
|---|---|---|
targets | string | natal or mutual |
start, end | instant | The range scanned, as { jd, datetime } |
points | array | The natal points scanned against, with the longitudes used. Absent for mutual |
moving, aspects, orb | The configuration the scan ran with | |
events[].moving | string | The moving body |
events[].aspect | string | The aspect |
events[].target | string | The point aspected: a natal body, ascendant, midheaven, or for mutual another moving body |
events[].enter | instant | When the pair came within orb |
events[].exacts | instant[] | Exact contacts, ascending. Empty for a window that never perfects: a body that turns retrograde inside the orb and withdraws |
events[].leave | instant | When the pair left orb |
events[].clamped_start | boolean | enter is the range start, not a real ingress: the pair was already in orb |
events[].clamped_end | boolean | leave 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
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"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();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
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
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
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.