Morphemeris DocsBeta

Profections

GET /v1/profections — Annual and monthly profections: the lord of the year and month, at one instant or over a range.

Profections

Annual and monthly profections of a natal chart, the simplest of the Hellenistic time-lord techniques. Each year of life advances the count one sign from the Ascendant: at age n the profected sign is n signs past the rising sign, that count is the profected house, and the sign's domicile ruler is the lord of the year. Each month of that year advances one sign further.

Ask for one instant to get the year and month in force, or for a range to get every year and month overlapping it as flat period records, ready for a timeline.

Text
GET  /v1/profections
POST /v1/profections

Credit cost: 1, or 2 with solar=true

Parameters

ParameterTypeRequiredDefaultDescription
datetimestringOne of datetime or jdNatal moment, ISO 8601 UTC
jdnumberOne of datetime or jdNatal moment as a Julian Day (UT1)
lat, lonnumberYesNatal location, for the Ascendant
atstringOne of at or start+endOne instant, ISO 8601 UTC: returns the year and month in force then (or at_jd)
start, endstringOne of at or start+endA range, ISO 8601 UTC: returns every period overlapping it. end after start, at most 120 years later (or start_jd, end_jd)
fromstringNoascendantThe point the count starts from: ascendant, midheaven, a body in bodies (moon), or a Hermetic lot (part_of_fortune, part_of_spirit, …). Only its sign matters
monthsbooleanNotrueInclude the twelve monthly sub-profections of each year
year_daysnumberNo365.2422Length of a profection year in days, for the mean-year boundaries. The default is the mean tropical year; 365.25 is the Julian year
solarbooleanNofalseAnchor each year to the Sun's real return to its natal degree and each month to its arrival 30° further on, searched in the chart's own zodiac. Costs 2 credits
bodiesstringNoplanetsBodies in the natal chart, so one can be named in from
siderealstringNoAyanamsha for the sidereal zodiac. The signs are then sidereal, and with solar=true the year turns at the sidereal return

Whole sign, always. Profections are defined on signs: an Ascendant at 29°59′ Virgo profects exactly as one at 0° Virgo, and the house is the whole-sign count from the starting sign whatever house system the natal chart is cast in. from only picks a starting sign.

Where a year begins is the one thing the count cannot decide, so there are two rules. By default (boundaries: "mean") a year is year_days days from birth and each month an equal twelfth. With solar=true (boundaries: "solar") each year begins at the solar return and each month when the Sun reaches 30°, 60°, … past its natal degree. The two agree on every house and lord; the years turn within a day of each other, and the months drift up to about three days apart by mid-year because the Sun moves faster through Capricorn than Cancer.

Nothing is profected before birth. A range that begins earlier is cut to the birth instant, which is a true boundary and is not flagged. An at before birth returns 400.

Response

JSON
{
  "data": {
    "from": "ascendant",
    "from_sign": "libra",
    "boundaries": "mean",
    "year_days": 365.2422,
    "months": true,
    "start": { "jd": 2461041.5, "datetime": "2026-01-01T00:00:00.000Z" },
    "end": { "jd": 2461406.5, "datetime": "2027-01-01T00:00:00.000Z" },
    "periods": [
      {
        "level": 1,
        "age": 35,
        "house": 12,
        "sign": "virgo",
        "lord": "mercury",
        "start": { "jd": 2461041.5, "datetime": "2026-01-01T00:00:00.000Z" },
        "end": { "jd": 2461207.08, "datetime": "2026-06-15T13:55:12.000Z" },
        "clamped_start": true,
        "clamped_end": false
      },
      {
        "level": 2,
        "age": 35,
        "month": 7,
        "house": 6,
        "sign": "pisces",
        "lord": "jupiter",
        "start": { "jd": 2461024.44, "datetime": "2025-12-14T22:31:00.000Z" },
        "end": { "jd": 2461054.88, "datetime": "2026-01-14T09:07:00.000Z" },
        "clamped_start": true,
        "clamped_end": false
      }
    ]
  },
  "meta": { "..." }
}
FieldTypeDescription
fromstringThe starting point, as requested
from_signstringIts sign in the natal chart: the first house of the count
boundariesstringmean or solar
year_daysnumberThe year length used. Absent for solar
monthsbooleanWhether month records are included
atinstantThe instant asked about, as { jd, datetime }. Present for an at query
start, endinstantThe range asked about. Present for a range query
periods[].levelnumber1 for a year, 2 for a month
periods[].agenumberCompleted years at the start of the year the record belongs to. Age 0 runs from birth to the first birthday
periods[].monthnumberMonth of the profected year, 1–12. Absent on a year record
periods[].housenumberThe profected house, 1–12, counted from the starting sign
periods[].signstringThe profected sign
periods[].lordstringThe lord of the year or month: the sign's classical domicile ruler
periods[].start, endinstantWhen the period begins and ends
periods[].clamped_startbooleanstart is the range's start, not the period's own
periods[].clamped_endbooleanend is the range's end, not the period's own

Records are flat, ordered by start then level, so a renderer draws one track per level and recovers the nesting from time containment. An at query returns the full year and month containing the instant, never clamped.

Examples

The lord of the year right now

Bash
curl "https://api.morphemeris.com/v1/profections?datetime=1990-06-15T14:30:00Z&lat=40.7&lon=-74&at=2026-03-01T00:00:00Z" \
  -H "Authorization: Bearer morphemeris_live_YOUR_KEY"
javascript
const res = await fetch(
  "https://api.morphemeris.com/v1/profections?datetime=1990-06-15T14:30:00Z&lat=40.7&lon=-74&at=2026-03-01T00:00:00Z",
  { headers: { Authorization: "Bearer morphemeris_live_YOUR_KEY" } }
);
const { data } = await res.json();
const year = data.periods.find((p) => p.level === 1);
console.log(`Age ${year.age}: ${year.house}th house, ${year.sign}, lord ${year.lord}`);
Python
import requests

res = requests.get(
    "https://api.morphemeris.com/v1/profections",
    params={
        "datetime": "1990-06-15T14:30:00Z", "lat": 40.7, "lon": -74,
        "at": "2026-03-01T00:00:00Z",
    },
    headers={"Authorization": "Bearer morphemeris_live_YOUR_KEY"},
)
year = next(p for p in res.json()["data"]["periods"] if p["level"] == 1)

A decade of years and months, anchored to the solar returns

Bash
curl "https://api.morphemeris.com/v1/profections?datetime=1990-06-15T14:30:00Z&lat=40.7&lon=-74&solar=true&start=2020-01-01T00:00:00Z&end=2030-01-01T00:00:00Z" \
  -H "Authorization: Bearer morphemeris_live_YOUR_KEY"

Profecting from the Lot of Fortune, years only

Bash
curl "https://api.morphemeris.com/v1/profections?datetime=1990-06-15T14:30:00Z&lat=40.7&lon=-74&from=part_of_fortune&months=false&start=2026-01-01T00:00:00Z&end=2036-01-01T00:00:00Z" \
  -H "Authorization: Bearer morphemeris_live_YOUR_KEY"

See Time Lords for the technique and the time-lords guide for building a timeline from the records. Planetary Returns gives the full chart at the solar return a profected year begins on.