Secondary progressions are computed by treating each day after birth as one year of life: to read someone's 30th year you cast a chart for the moment 30 days after they were born, then compare those progressed positions to the original natal chart. With a Western astrology API you do this in two calls to the same tropical chart endpoint, deriving the progressed date in your own code. This guide walks through the day-for-a-year math, the exact endpoint shapes on api.vedika.io, and runnable examples.
What secondary progressions actually are
Secondary progression is one of the oldest predictive methods in the Western tradition, traceable to the day-for-a-year symbolism Ptolemy discusses in the Tetrabiblos. The rule is deceptively simple: one day of ephemeris motion after birth equals one year of life. Because the Sun moves roughly one degree per day, the progressed Sun advances about a degree a year, and the fast-moving progressed Moon sweeps the whole zodiac in roughly 27 to 28 years, changing sign every two-and-a-half years or so.
That makes progressions a slow, internal timing layer. They describe maturation and unfolding rather than external events the way transits do. The two techniques are usually read together, and both are entirely deterministic once you have an accurate ephemeris.
The two charts you compare
- Natal chart — the tropical chart for the exact birth moment and place.
- Progressed chart — a natal-style chart cast for the progressed datetime (birth + one day per year of age), but conventionally read using the natal birthplace and house framework.
A reading then looks at progressed-to-natal aspects (for example progressed Moon conjunct natal Venus) and progressed-to-progressed aspects, alongside which natal house the progressed planet now occupies.
The day-for-a-year calculation
The core of the technique is converting an age into a progressed datetime. The clean version measures elapsed time precisely rather than rounding to whole days, so the progressed Moon lands on the right degree.
// Derive the progressed datetime for a given target date.
// One mean solar year of life maps to one mean solar day after birth.
function progressedDatetime(birthIso, targetIso) {
const birth = new Date(birthIso);
const target = new Date(targetIso);
const MS_PER_DAY = 86_400_000;
const TROPICAL_YEAR_DAYS = 365.242_19; // mean tropical year
// Years of life elapsed between birth and the target date.
const yearsElapsed =
(target.getTime() - birth.getTime()) / (MS_PER_DAY * TROPICAL_YEAR_DAYS);
// Add that many DAYS after birth to get the progressed moment.
const progressedMs = birth.getTime() + yearsElapsed * MS_PER_DAY;
return new Date(progressedMs).toISOString();
}
// Example: progressed chart on a person's 30th-birthday window.
progressedDatetime("1990-04-12T07:25:00Z", "2020-04-12T00:00:00Z");
// -> roughly 30 days after birth, in ISO form
Once you have progressedDatetime, you compute the natal chart and the progressed chart with the same endpoint, the same coordinates, and the same timezone — only the datetime differs. That symmetry is the whole trick, and it is why a single Western chart endpoint is all you need.
The endpoints you call
Vedika exposes 700+ API operations across 25 domains (704 enumerated in June 2026), spanning Vedic (sidereal), Western (tropical), and KP from one base URL. For progressions you need exactly one computation endpoint plus, optionally, the natural-language query endpoint for interpretation.
| Purpose | Method & path | Notes |
|---|---|---|
| Compute a tropical chart | POST /v2/astrology/* | Flat body: datetime, latitude, longitude, timezone. Called twice (natal + progressed). |
| AI interpretation | POST /api/v1/astrology/query | Nested birthDetails; optional speed: "fast". |
| Streaming interpretation | POST /api/v1/astrology/query/stream | Server-Sent Events for token-by-token output. |
Authentication is a single header, x-api-key: vk_live_*, on every request. There is also a free sandbox that needs no key, so you can validate the request and response shapes before wiring billing in.
Step 1 — natal chart (cURL)
curl -X POST https://api.vedika.io/v2/astrology/western/natal \
-H "x-api-key: vk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-04-12T07:25:00",
"latitude": 28.6139,
"longitude": 77.2090,
"timezone": "Asia/Kolkata"
}'
Step 2 — progressed chart (cURL)
Pass the progressed datetime you computed, keeping the natal coordinates and timezone identical so the only moving part is time:
curl -X POST https://api.vedika.io/v2/astrology/western/natal \
-H "x-api-key: vk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"datetime": "1990-05-12T07:25:00",
"latitude": 28.6139,
"longitude": 77.2090,
"timezone": "Asia/Kolkata"
}'
The response carries tropical longitudes for each body. Your code then computes progressed-to-natal aspects by comparing the two longitude sets within an orb you choose (commonly 1 degree for progressed work, since the technique is slow).
Putting the two charts together in code
Here is an end-to-end sketch using a generic HTTP client. It fetches both charts and flags the tightest progressed-Moon-to-natal contacts — the contacts most practitioners weight first.
import requests
from datetime import datetime, timezone
BASE = "https://api.vedika.io"
HEADERS = {"x-api-key": "vk_live_your_key", "Content-Type": "application/json"}
TROPICAL_YEAR = 365.24219
def chart(dt_iso, lat, lon, tz):
body = {"datetime": dt_iso, "latitude": lat, "longitude": lon, "timezone": tz}
r = requests.post(f"{BASE}/v2/astrology/western/natal", json=body, headers=HEADERS)
r.raise_for_status()
return r.json()
def progressed_iso(birth_iso, target_iso):
b = datetime.fromisoformat(birth_iso).replace(tzinfo=timezone.utc)
t = datetime.fromisoformat(target_iso).replace(tzinfo=timezone.utc)
years = (t - b).total_seconds() / (86400 * TROPICAL_YEAR)
prog = b.timestamp() + years * 86400
return datetime.fromtimestamp(prog, tz=timezone.utc).isoformat()
birth = "1990-04-12T07:25:00"
lat, lon, tz = 28.6139, 77.2090, "Asia/Kolkata"
natal = chart(birth, lat, lon, tz)
prog_dt = progressed_iso(birth + "+00:00", "2020-04-12T00:00:00+00:00")
progressed = chart(prog_dt, lat, lon, tz)
# Compare progressed Moon against every natal body within a 1-degree orb.
def angle(a, b):
d = abs(a - b) % 360
return min(d, 360 - d)
ASPECTS = {0: "conjunction", 60: "sextile", 90: "square",
120: "trine", 180: "opposition"}
prog_moon = next(p for p in progressed["planets"] if p["name"] == "Moon")
for np in natal["planets"]:
sep = angle(prog_moon["longitude"], np["longitude"])
for exact, name in ASPECTS.items():
if abs(sep - exact) <= 1.0:
print(f"Progressed Moon {name} natal {np['name']} (orb {sep - exact:+.2f})")
Field names in your response may differ slightly by chart variant; inspect a sandbox response first and map longitude and name to whatever the payload uses. The logic — two calls, one comparison loop — does not change.
Why the ephemeris underneath matters
Progressions are unforgiving about precision because they multiply small errors. A tenth of a degree of natal Moon error becomes a multi-month timing error once you stretch a day into a year. Positions here come from the XALEN Ephemeris, Vedika's own open-source engine (Apache-2.0, published to crates.io as xalen, PyPI as xalen, and npm as @xalen/wasm), built with around 2,200 tests.
Its longitudes are validated against JPL DE440 and swetest, with no charts deviating beyond 0.1 degrees across a reproducible JPL DE440 benchmark. That is astronomical precision for the planetary longitudes the day-for-a-year math depends on — it is a statement about the ephemeris, not a claim about astrological interpretation. Because the engine is open source, you can audit exactly how a position was derived, which is rare for a hosted astrology API.
Layering an AI reading on top
Computed aspects answer what is forming; many integrations also want readable text. After you have the progressed contact, pass the question and birth details to the AI query endpoint:
curl -X POST https://api.vedika.io/api/v1/astrology/query \
-H "x-api-key: vk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"question": "My progressed Moon is forming a trine to my natal Venus this year. What does that suggest?",
"birthDetails": {
"datetime": "1990-04-12T07:25:00",
"latitude": 28.6139,
"longitude": 77.2090,
"timezone": "Asia/Kolkata"
},
"speed": "fast"
}'
The interpretation is grounded on the code-computed chart rather than a guessed one, and astrological statements trace to classical Western sources actually used in practitioner training, such as Ptolemy's Tetrabiblos. Output is available in 30 languages, and there is a streaming variant over Server-Sent Events when you want progressive rendering in a UI.
How this fits a multi-system integration
Plenty of hosted astrology APIs do one job well. Prokerala (around $19/mo) has solid Vedic coverage, AstrologyAPI.com (around $29/mo) offers a broad endpoint catalog, and RoxyAPI (around $39/mo) is a capable general-purpose option. Their genuine strength is breadth of pre-built endpoints for common reports.
Vedika's differentiator for progression work specifically is that the Western (tropical), Vedic (sidereal), and KP systems live behind one base URL, one key, and one auth header — so the same integration that progresses a tropical chart can also return a sidereal Vedic chart or a KP analysis without a second vendor. It also publishes a leading public astrology MCP server (npx @vedika-io/mcp-server, 36 tools), so an MCP-compatible client or LLM agent can call these computations as tools directly. Pricing runs from $12/mo (Starter) through $60 (Professional), $120 (Business, which adds the fast path and voice) and $240 (Enterprise), with per-query cost in the $0.01–$0.05 range.
Key facts
- Secondary progressions use the day-for-a-year rule: one ephemeris day after birth = one year of life.
- You compute them with two calls to the same Western (tropical) chart endpoint — natal and progressed — differing only in
datetime. - V2 computation endpoints take a flat body:
datetime, latitude, longitude, timezone; auth isx-api-key: vk_live_*. - Positions come from the XALEN Ephemeris (Apache-2.0; crates.io/PyPI/npm), validated against JPL DE440 and
swetestwith no chart beyond 0.1° across a reproducible JPL DE440 benchmark. - One API exposes Western, Vedic, and KP — plus an MCP server with 36 tools and output in 30 languages.
- Test request and response shapes free in the sandbox before adding a key.
Bringing it all together
Secondary progressions reduce to arithmetic plus a precise ephemeris: convert age to a progressed datetime, fetch two tropical charts, and compare longitudes. Because the same endpoint serves both charts and the same key serves Western, Vedic, and KP, you can build a full progression feature without juggling vendors. Start in the free sandbox, review the API docs for the exact response fields, check pricing for the per-query tiers, and see transits vs progressions for how to layer the two timing techniques together.