Product-updates

Transit Scan v2: Significance Scoring, Retrograde Activation Windows, and Fixed Minor Aspects

Transit Scan v2 shipped on natal-transits. Significance scoring, orb-at-query, retrograde activation windows, and asteroids/TNOs as transiting bodies - opt-in, backward-compatible.

OK

Oleg Kopachovets

CTO & Co-Founder

July 25, 2026
12 min read
237 views
Transit Scan v2 engine launch announcement
Transit Scan v2 engine launch announcement
0%

What shipped

On July 20-21, 2026, we shipped a second calculation path for POST /api/v3/charts/natal-transits. We are calling it Transit Scan v2. It is entirely opt-in - the endpoint keeps returning response_version: 1 and the exact same payload shape it always has unless you pass one of the new parameters. Nothing you have already built breaks.

If you do opt in, you get a transit engine built for people who need to know which contacts matter, not just which contacts exist: a 0-100 significance score per aspect, exact orb and applying/separating direction at any point in time, retrograde stations collapsed into single activation windows instead of duplicate events, and asteroids, centaurs, and trans-Neptunian objects available as transiting bodies for the first time. Two long-standing bugs are also fixed: sextiles and the minor aspect family were silently missing from every response, and there was no way to scan a multi-decade window for slow-moving bodies without stitching together dozens of one-year requests yourself.

This post is for the audience actually calling this endpoint - people building timing dashboards, trading signal feeds, or personal-development apps that need transit data they can trust and rank, not a stream of raw ephemeris facts to re-derive on their own.

The problem v1 had

The default active-points set in v1 includes 13 bodies, and the Moon dominates that list by volume - it moves roughly 13 degrees a day and touches something new every couple of days. Run a six-month scan with defaults and you get back hundreds of events, most of them Moon conjunctions and squares that mean almost nothing on their own. Buried in that noise is the one outer-planet transit that actually matters for the month. v1 gave you no way to separate the two without writing your own weighting logic on top of raw aspect lists.

On top of the noise problem, two things were flatly broken. Sextiles - one of the five Ptolemaic aspects, not an edge case - never made it into the response. Neither did the minor aspect family (semisextile, semisquare, sesquiquadrate, quincunx) or the harmonic family (quintile, biquintile). If your product promised "we calculate the five major aspects" and a user cross-checked against another chart source, your sextile column would just be empty. And you could target asteroids and TNOs in a natal chart, but you could never ask "when does transiting Chiron aspect my natal Sun" - Chiron, centaurs, and dwarf planets were natal-only, never transiting.

v2 fixes both bugs and adds the ranking layer on top.

significance_score and is_retrograde: rank instead of dump

Every activation in v2 now carries a significance_score from 0 to 100. It is not a flat lookup - it is computed per transit from four factors: the aspect type (conjunction/square/opposition score higher than trine/sextile, which score higher than minor aspects), the natal target (luminaries, angles, and your chart ruler outrank ordinary planets), the transiting body (Uranus/Neptune/Pluto and TNOs outrank the Moon by a wide margin, since a five-minute Moon square is not the same event as a Pluto conjunction), the current orb, and whether the transiting body is stationary on the degree. A Pluto conjunction to the Sun within a fifth of a degree of a station scores 99. A Moon sextile to Neptune at nearly a degree scores 1.
This is the field that turns a list of every contact happening this month into "here are the three that matter." If you are building a "what's active for you right now" screen, you sort by significance_score and show the top handful instead of everything. That sorting logic - deciding that an outer-planet station on an angle outweighs a fast Moon aspect - is genuine domain expertise to encode correctly; the endpoint does it for you and returns a number you can just sort on.
is_retrograde rides along on the same activation, flagging whether the transiting body is retrograde at the moment you queried. It does not feed into the score - it is there so you can label the event in your UI ("Saturn Rx square Moon") without a separate lookup against ephemeris data.

orb_at_query, applying_at_query, and query_date: know exactly how tight, right now

v1's orb field on an event was close to useless for anything except the instant of exact perfection, because v1 events are point-in-time hits. v2 activations report peak_orb, the tightest separation the aspect ever reaches - which is near zero for anything that goes exact, so it does not tell you how close the aspect is today.
That is what orb_at_query solves. Pass a query_date (it defaults to the start of your scan window, or today if you did not set a window) and every activation returns orb_at_query: the actual angular separation between the transiting body and the natal point on that specific date. Alongside it, applying_at_query tells you whether the orb is currently closing (the aspect is building) or opening (it already peaked and is separating) - with retrograde motion accounted for automatically, so a planet that stations and reverses direction mid-transit reports the correct applying/separating state without you tracking speed yourself.
For a "what's active right now" widget, this is the pair of fields you actually render: how tight is it (orb_at_query), and is it getting tighter or looser (applying_at_query). Passing query_date at all is enough to opt into v2 on its own.

peak_orb and exactness: catch the tension that never quite lands

Not every meaningful transit perfects. A slow outer planet can approach a natal point, get to within a tenth of a degree, and then turn retrograde and pull away without ever hitting an exact 0.0 orb - a real astronomical near-miss that traditionally reads as building pressure that partially resolves rather than fully discharges. v1 had no concept of this; if the aspect never went exact, it simply never appeared.

v2 activations carry exactness, either "exact" or "close_approach", and peak_orb, the minimum separation the pass actually reached. Close approaches are opt-in via include_close_approaches: true, with your orb parameter setting the threshold - only near-misses with peak_orb at or under that value come back, while exact perfections are always included regardless of the threshold. This is the field an orb-stepper UI control needs to do anything at all in v2, since orb on a flat event is always zero for an exact hit and filters nothing.

Close approaches show up almost exclusively around retrograde stations, which is exactly the astronomy you would expect - a planet has to slow down and reverse to graze an aspect and pull back without completing it. Treat a close approach as meaningfully weaker than an exact hit; it is signal about building tension, not a completed event, and the API distinguishes the two so you do not have to guess from raw orb numbers.

granularity: "activations" - the field a "what's active" dashboard actually needs

This is the single most useful addition for anyone building a timing dashboard. A retrograde outer-planet transit does not touch a natal point once - it commonly touches it two or three times as the planet moves direct, stations retrograde and crosses back over the same degree, then stations direct and crosses forward again. In v1's flat event list, that shows up as two or three disconnected records with no field linking them, and a naive UI renders three separate "Saturn square Moon" cards for what a user experiences as one ongoing period.

Pass granularity: "activations" and v2 groups those passes into a single window: window_start, window_end, peak_datetime (the pass with the tightest orb), exact_hits (every precise perfection inside the window), pass_count, and stationary_on_target (whether a station happens right on the aspect degree, which intensifies it). If your scan window cuts off before the retrograde loop resolves, window_clipped: true tells you the activation likely continues past your window's edge, so you know to widen scan_range rather than treat the transit as finished.
Computing this yourself means detecting sign changes in relative motion, matching passes to the same natal target and aspect, and handling the edge case where your scan window bisects a loop - not a huge amount of code, but the kind of thing that is easy to get subtly wrong (miscounting passes, double-counting a station, or clipping a window without flagging it) and tedious to test against real ephemeris data. granularity: "activations" returns the finished data structure.

scan_range: multi-year windows for slow movers

The standard transit_time.date_range window caps at 367 days, which works fine for personal planets but is close to useless for outer planets and TNOs - a Neptune transit to a natal point can take years to complete its full retrograde cycle, and you would need dozens of chained one-year requests to see the whole arc. scan_range opens a window of up to roughly 50 years in a single call, is opt-in on its own (passing it triggers v2 even with no other new parameter), and treats the end date as inclusive, so a same-day start_date/end_date pair is a valid one-day scan. Ask for a range outside available ephemeris coverage and you get a 422 instead of a silently wrong or empty result.

Asteroids, centaurs, and TNOs as transiting bodies

options.active_points now accepts asteroids (Ceres, Pallas, Juno, Vesta), centaurs (Chiron, Pholus, Nessus), and TNOs/dwarf planets (Eris, Sedna, Haumea, Makemake) as transiting bodies, not just natal targets. If your product covers outer-point work - Chiron transits, Eris cycles, generational-body timing - you can now ask "when does transiting Pholus aspect my natal Mars" directly instead of working around the limitation. Note the current constraint in the other direction: these bodies work as transiters now, but are not yet supported as target_points (natal targets) - that is on our list, not shipped yet.

Before and after, side by side

A legacy call, unchanged, still returns exactly what it always has:

json
1POST /api/v3/charts/natal-transits
2{ "subject": { "...": "..." },
3 "transit_time": { "date_range": { "start_date": {"year":2026,"month":1,"day":1},
4 "end_date": {"year":2026,"month":6,"day":1} } } }
5
6// response_version: 1 - flat events, Moon-heavy, no sextiles, no score

A v2 call asking for the sextile/minor bug fix, a multi-year window, and grouped retrograde windows with significance ranking:

json
1POST /api/v3/charts/natal-transits
2{ "subject": { "...": "..." },
3 "scan_range": { "start_date": {"year":2024,"month":1,"day":1},
4 "end_date": {"year":2028,"month":1,"day":1} },
5 "options": { "active_points": ["Saturn","Uranus","Neptune","Pluto","Chiron"] },
6 "aspect_families": ["ptolemaic","minor"],
7 "granularity": "activations",
8 "query_date": "2026-07-25" }
9
10// response_version: 2
11// activations[0]: { "transiter":"Saturn","target":"Moon","aspect":"square",
12// "orb_at_query":1.02,"applying_at_query":true,"significance_score":57,
13// "window_start":"2026-05-01T...","window_end":"2026-11-12T...",
14// "pass_count":2,"peak_datetime":"2026-08-19T...","window_clipped":false }

Same subject, same time frame in spirit. The second call comes back as a ranked, deduplicated, four-year-spanning result set instead of a Moon-dominated pile of flat events missing half the aspect vocabulary.

Time to build this yourself versus one request

Every field described above is something you can compute from raw ephemeris data with enough engineering time. Retrograde activation windows require detecting direction changes and matching repeat passes to the same natal contact across an arbitrary date range. A significance model requires encoding real astrological weighting - which aspects, which points, which transiting bodies outrank which others, and how orb and station proximity should scale the result - then tuning it against cases an astrologer would sanity-check by hand. Close-approach detection means tracking a separation curve, finding its local minimum, and deciding whether it crossed zero or turned back. None of it is exotic, but all of it is real work: weeks of implementation plus an ongoing correctness burden every time you touch orb tables or station logic.

granularity: "activations", significance_score, and include_close_approaches replace that work with three request parameters. You spend your engineering time on the product surface - the dashboard, the trading signal logic, the notification rules - instead of re-deriving retrograde-loop detection from Swiss Ephemeris output.

Where this fits in a timing product

A "what's active right now" dashboard. Query with granularity: "activations" and today's query_date, sort by significance_score, and render the top few contacts with their orb_at_query and applying_at_query state. This is close to the whole feature.
Trading and market-timing tools. scan_range plus outer-planet active_points gets you multi-year outer-planet cycles in one call, and significance_score lets you filter for high-weight stations and conjunctions without hand-rolling the ranking logic your model depends on.
Personal-development and coaching apps. include_close_approaches surfaces the "building but not yet resolved" transits that make for good "here's what's approaching" copy, distinct from transits that already peaked.
Any app currently showing incomplete aspect data. If you built against v1 defaults, you were missing sextiles and the entire minor aspect family without knowing it. Adding aspect_families: ["ptolemaic","minor"] to your existing calls is the fix, and it is opt-in - it will not change any response you are not explicitly requesting.

Backward compatibility and how to opt in

Every existing integration against natal-transits keeps working exactly as it does today. v2 activates only when you send options.active_points with a non-default set, aspect_families, aspects, target_points, granularity, scan_range, or query_date. Check response_version in the response if you want to confirm which path served a given request. Unknown values in aspects or aspect_families return a 400; a scan_range outside ephemeris coverage returns a 422.

Pricing

Transit Scan v2 is available at every existing pricing tier - it is the same natal-transits endpoint you already have access to, with new opt-in parameters. No new endpoint, no new line item, no tier change required to start using it.
See /pricing for the full tier table.

What's next

We are extending target-point support to asteroids and TNOs, so you will be able to ask about transits to Chiron or Eris in the natal chart, not just transits from them. Declination aspects - parallels and contraparallels - and antiscia are planned as a separate phase. If you are building against significance scoring and want a field we have not covered, tell us; the scoring model is new enough that we are still tuning it against real integration feedback.
Questions or integration issues, reach us via /contact or the API docs.
Oleg Kopachovets

Oleg Kopachovets

CTO & Co-Founder

Technical founder at Astrology API, specializing in astronomical calculations and AI-powered astrology

More from Astrology API