Log in/Sign up

Vedic Astrology REST API

A JSON HTTP API over the Jagannatha Hora calculation engine. Send a birth date, time and place; get back the full Vedic chart — 23 divisional charts, dashas, yogas, doshas, ashtakavarga, transits, panchang, muhurta and compatibility. 15 endpoints, all open with no API key.

Start here

The API is live at https://jagannatha-hora-359167915530.europe-west1.run.app. There is nothing to sign up for. Send a POST with a JSON body and read the JSON that comes back. This one command returns a complete Vedic birth chart:

The whole thing, in one call
curl -X POST "https://jagannatha-hora-359167915530.europe-west1.run.app/horoscope" \
  -H "content-type: application/json" \
  -d '{"date":"1990-01-01","time":"06:30:00","place":"Bengaluru",
       "latitude":12.9716,"longitude":77.5946,"timezone":5.5}'

If you do not know the coordinates for a birth place, resolve it first with GET /location/search, which searches an index of more than 162,000 cities and returns latitude, longitude and the timezone offset. That is the normal two-step flow: one lookup, then one calculation.

If you are wiring this into an AI agent rather than an application, use the MCP server instead. It exposes the same engine as 33 individually callable tools, so a model can ask for just the dashas or just the ashtakavarga and get kilobytes back rather than the megabytes /horoscope returns.

Machine-readable versions of this page

This page exists in three more formats, with the same facts.

Conventions that apply everywhere

No API key
Every endpoint is open — no key, no token, no signup. CORS is open too, so browser-side calls work.
Rate limits
Each POST endpoint has its own per-minute limit, listed with the endpoint below and counted per client IP address (an IPv6 client is counted by its /64 network). The GET endpoints are not rate limited. Over the limit, the response is 429 with the body {"error": "Rate limit exceeded: 30 per 1 minute"}. The MCP server allows 30 requests a minute per IP.
Same inputs, same output
These are astronomical calculations, not model inferences: the same inputs give the same output until the calculation engine changes. /horoscope and /marriage-match return engine_revision, an integer that goes up whenever calculated values change, so cache by input and engine_revision. The exception is /saturn-timeline, whose current phase and months remaining are measured from today's date. /panchang, /gochar and /gochar/events also send Cache-Control: public, max-age=21600.
Dates, times and time zones
Dates are YYYY-MM-DD and times are HH:MM:SS on a 24-hour clock, always as strings. Time zones are a decimal hour offset from UTC (5.5, not "Asia/Kolkata"). /horoscope, /gochara and /surya-siddhanta work out the historically correct birth offset, daylight saving included, from the coordinates and date unless you send timezone_mode "file"; /marriage-match, /gochara/range and /muhurta always do. /panchang, /gochar, /gochar/events and every event_timezone are worked out from the coordinates the same way. In all of these your value is the fallback where no time zone is known for the place. /saturn-timeline and /planet-ingress use the offset exactly as you send it.
Responses are gzipped
Responses over 1 KB are gzip-compressed. This matters most for /horoscope, where it turns megabytes into hundreds of kilobytes. Send Accept-Encoding: gzip — every common HTTP client does by default.
Two kinds of input error
A missing, mistyped or out-of-range field, or a value outside an allowed list, is a 422 whose detail lists each problem with the field's location. A well-formed request the calculation cannot serve — a range that is too long, an unknown planet — is a 400 with a message. Either way the detail names the field and the limit, so it is worth showing to your users.

The shared birth-details block

Seven endpoints take a birth chart as their subject: /horoscope, /surya-siddhanta, /marriage-match (two of them), /gochara, /gochara/range, /muhurta and /saturn-timeline. The two blocks of fields most of them share are listed once here rather than repeated below.

POST /horoscope takes the full block below: six required fields, then calculation settings that all have defaults and that you can ignore until you need them.

Birth details and calculation settings for POST /horoscope
ParameterTypeRequiredDefaultNotes
datestringYes—Birth date, YYYY-MM-DD. Year 1800-2100, month 1-12, day 1-31.
timestringYes—Birth time, HH:MM:SS (24-hour). Hour 0-23, minute 0-59, second 0-59.
placestringYes—Birth place name, echoed in the response. The coordinates decide the calculation.
latitudenumberYes—Decimal degrees, -90 to 90, north positive. Birth places beyond about 66.5° north or south (inside the polar circles) are rejected with 422.
longitudenumberYes—Decimal degrees, -180 to 180, east positive.
timezonenumberYes—UTC offset in hours, -12 to 14 (5.5 for IST). By default the API works out the historically correct offset, daylight saving included, from the coordinates and date, and uses this value only where no time zone is known for the place. See timezone_mode.
elevationnumberNo0.0Metres above sea level.
genderstringNonull"male" or "female" ("m" and "f" also work). A few classical yogas depend on gender; when it is omitted they are left out of the yoga list rather than guessed. Any other value is rejected with 422.
ayanamsa_modestringNo"LAHIRI"One of the 20 listed modes, case-insensitive; KRISHNAMURTI, FAGAN_BRADLEY, SRI_YUKTESHWAR and LAHARI are accepted for KP, FAGAN, YUKTESHWAR and LAHIRI too. SIDM_USER needs ayanamsa_value. Any other value is rejected with 422.
ayanamsa_valuenumberNonullYour own ayanamsa in degrees, -30.0 to 30.0, used with ayanamsa_mode SIDM_USER. SIDM_USER without a value is rejected with 422.
calculation_typestringNo"drik""drik" (modern positions) or "ss" (Surya Siddhanta). Case-insensitive. With "ss" the chart also carries a surya_siddhanta section.
node_typestringNo"mean"Rahu/Ketu as the "mean" or the "true" lunar node. Any value other than "true" gives the mean node.
bhava_madhya_methodintegerNo1House system for bhava_chart, 1-5: 1 = equal houses with the lagna at the middle, 2 = equal houses with the lagna at the start, 3 = Sripati, 4 = KP (houses start at the Placidus cusps), 5 = whole sign. Whatever the method, bhava_chart's 12 slots are arranged by sign (slot 0 = Aries), with house 1 in the slot of the lagna's sign.
timezone_modestringNo"auto""auto" works out the historical offset from the coordinates and date, falling back to timezone where no zone is known; "file" uses timezone exactly as sent. Either way birth_details in the response reports timezone_used, timezone_derived and timezone_source. Any other value is rejected with 422.
languagestringNo"en"Language for names in the response: en, hi, ka, ta or te.
pravesha_typeintegerNo00 = natal chart, 1 = annual (varsha pravesha), 2 = tithi pravesha.
yearsintegerNo1Year number for annual charts, 1-120.
monthsintegerNo1Month number for monthly charts, 1-12.
sixty_hoursintegerNo1Sixty-hour period number for hora progressions, 1-1000.
divisional_chart_factorintegerNo11-300. Names the divisional chart that chart_method applies to (1 = D-1, 9 = D-9 and so on). It does not select which charts come back: divisional_charts always holds all 23. A factor that is not one of those 23 is reported in request_notes.
chart_methodintegerNo11-6. Construction method for the chart named by divisional_chart_factor; how many methods exist depends on the chart (D-1 has one, D-9 five, D-2 six). An unavailable method falls back to 1 and is reported in request_notes.
base_rasiintegerNonull0-11 (0 = Aries). Applies only to custom divisional charts, which this endpoint does not return; if set, it is reported in request_notes and otherwise has no effect.
count_from_end_of_signbooleanNonullApplies only to custom divisional charts, which this endpoint does not return; if set, it is reported in request_notes and otherwise has no effect.
varnada_methodintegerNo1Method for the varnada outputs (house_varnadas, the Varnada entries in amsa_rulers and the Varnada dasha): methods 1 to 4. A higher value falls back to 1 and is reported in request_notes; a negative value is rejected with 422.
tamil_month_methodintegerNo3How the Tamil solar month is reckoned: 0, 1, 2 or 3. 1 starts the month at sunset, 2 at 10 AM, 3 at midday UTC.
kali_start_yearintegerNo13Naming of the sixty-year cycle: 1 starts at Prabhava (South Indian), 13 at Pramaadhi (North Indian).

The natal block

POST /gochara, POST /gochara/range and POST /muhurta take this smaller block for the birth chart, plus their own fields listed with each endpoint. They take none of the other calculation settings above; /gochara adds node_type and timezone_mode. /saturn-timeline, /surya-siddhanta and /marriage-match list all their own fields.

Birth details for POST /gochara, POST /gochara/range and POST /muhurta
ParameterTypeRequiredDefaultNotes
datestringYes—Birth date, YYYY-MM-DD. Year 1800-2100.
timestringYes—Birth time, HH:MM:SS (24-hour).
placestringNo""Birth place name, echoed in the response. The coordinates decide the calculation.
latitudenumberYes—Decimal degrees, -90 to 90. Birth places beyond about 66.5° north or south (inside the polar circles) are rejected with 422.
longitudenumberYes—Decimal degrees, -180 to 180.
timezonenumberYes—UTC offset at birth in hours, -12 to 14. The API works out the historically correct offset, daylight saving included, from the coordinates and date, and uses this value only where no time zone is known for the place.
elevationnumberNo0.0Metres above sea level.
ayanamsa_modestringNo"LAHIRI"One of the listed modes except SIDM_USER, case-insensitive; KRISHNAMURTI, FAGAN_BRADLEY, SRI_YUKTESHWAR and LAHARI are accepted for KP, FAGAN, YUKTESHWAR and LAHIRI too. Any other value is rejected with 422, SIDM_USER included, since no ayanamsa_value is taken here.

Ayanamsa modes

The ayanamsa_mode field accepts these 20 values.

LAHIRI, TRUE_CITRA, TRUE_LAHIRI, KP, FAGAN, RAMAN, USHASHASHI, YUKTESHWAR, SURYASIDDHANTA, SURYASIDDHANTA_MSUN, ARYABHATA, ARYABHATA_MSUN, SS_CITRA, TRUE_REVATI, SS_REVATI, TRUE_PUSHYA, TRUE_MULA, KP-SENTHIL, SENTHIL, SIDM_USER

LAHIRI is the default and the most widely used in Indian practice. The choice shifts every sidereal longitude, so pick one and stay with it. Names are case-insensitive, and KRISHNAMURTI, FAGAN_BRADLEY, SRI_YUKTESHWAR and LAHARI are accepted for KP, FAGAN, YUKTESHWAR and LAHIRI. SIDM_USER uses your ayanamsa_value and needs it; only /horoscope and /surya-siddhanta take one. Every endpoint rejects any other value with 422 and a message listing the accepted modes; it is never replaced by LAHIRI. /saturn-timeline accepts LAHIRI or RAMAN only.

All 15 endpoints

Listed most useful first. Every one of them returns JSON.

POST/horoscope

The complete Vedic birth chart for a birth moment.

The workhorse endpoint. One call returns every calculation the engine performs for a chart: 23 divisional charts, nakshatras and padas, yogas, doshas, chara karakas, sahams, upagrahas, special lagnas, sphutas, arudhas, house relationships, planetary states, Shad Bala and the other strengths, ashtakavarga, graha and rasi dashas, Saturn transits and longevity reference computations. The response is large — several megabytes of JSON — and gzip-compressed on the wire, so cache it on your side.

Rate limit
30 requests/minute per IP
Authentication
None. Open endpoint, no key required.
Response keys
birth_details, horoscope, engine_revision

Takes the shared birth-details block.

Example request
curl -X POST "https://jagannatha-hora-359167915530.europe-west1.run.app/horoscope" \
  -H "content-type: application/json" \
  -d '{
    "date": "1990-01-01",
    "time": "06:30:00",
    "place": "Bengaluru",
    "latitude": 12.9716,
    "longitude": 77.5946,
    "timezone": 5.5
  }'
Example response — TRUNCATED excerpt, see the full key list below
{
  "birth_details": {
    "date": "1990-01-01",
    "time": "06:30:00",
    "place": "Bengaluru",
    "latitude": 12.9716,
    "longitude": 77.5946,
    "timezone": 5.5,
    "timezone_used": 5.5,
    "timezone_derived": 5.5,
    "timezone_source": "derived",
    "request_settings": {
      "ayanamsa_mode": "LAHIRI",
      "calculation_type": "drik",
      "node_type": "mean",
      "bhava_madhya_method": 1
      /* …14 more settings */
    }
  },
  "horoscope": {
    "ayanamsa_value": 23.7174169601642,
    "julian_day": 2447892.7708333335,
    "nakshatra_pada": {
      "Ascendant": {
        "nakshatra": "Moola",
        "nakshatra_number": 19,
        "pada": 4,
        "nakshatra_lord": "Kethu",
        "degrees_in_nakshatra": 13.0166
      }
      /* …the other bodies */
    },
    "divisional_charts": {
      "D-1_rasi": {
        "Ascendant": { "sign": "Sagittarius", "longitude": 13.0166 },
        "Moon": { "sign": "Aquarius", "longitude": 3.3941 }
        /* …the other bodies */
      }
      /* …22 more charts */
    }
    /* …29 more keys, listed in full below */
  },
  "engine_revision": 6
}
  • birth_details echoes your input plus timezone_used, timezone_derived and timezone_source (the offset actually applied and where it came from) and request_settings (every calculation setting the chart was computed with).
  • engine_revision is an integer that goes up whenever calculated values change. The same inputs return the same chart until it changes, so cache by input and engine_revision.
  • divisional_charts always holds all 23 vargas; divisional_chart_factor only names the chart chart_method applies to.
  • If you only need one slice — the dashas, the ashtakavarga, the yogas — the MCP server exposes each as its own tool and returns kilobytes instead of megabytes.

POST/surya-siddhanta

A natal chart computed by the classical Surya Siddhanta method.

Surya Siddhanta positions for a birth moment: the lagna, the nine bodies with sign, degree, nakshatra and pada, daily motion and retrograde flag, and the Surya Siddhanta panchanga (tithi, nakshatra, yoga, karana, vaara, sunrise and sunset). The ayanamsa block reports the Surya Siddhanta ayanamsa and its difference from the mode you ask for; positions are expressed in that requested ayanamsa. Names are always in English. Every other endpoint uses modern (drik) positions.

Rate limit
60 requests/minute per IP
Authentication
None. Open endpoint, no key required.
Response keys
birth_details, surya_siddhanta
Body fields for /surya-siddhanta
ParameterTypeRequiredDefaultNotes
datestringYes—Birth date, YYYY-MM-DD; must be a real calendar date. Year 1800-2100.
timestringYes—Birth time, HH:MM:SS (24-hour).
latitudenumberYes—Decimal degrees, -90 to 90. Places beyond 66° north or south are rejected with 400.
longitudenumberYes—Decimal degrees, -180 to 180.
timezonenumberYes—UTC offset at birth in hours, -12 to 14. By default the API works out the historically correct offset, daylight saving included, from the coordinates and date, and uses this value only where no time zone is known for the place. See timezone_mode.
placestringNo""Place name, echoed in the response.
elevationnumberNo0.0Metres above sea level. Echoed in the response only.
timezone_modestringNo"auto""auto" works out the offset from the coordinates and date; "file" uses timezone exactly as sent. Any other value is rejected with 422.
ayanamsa_modestringNo"LAHIRI"The ayanamsa the positions are expressed in and the Surya Siddhanta ayanamsa is compared against. One of the 20 listed modes, case-insensitive; KRISHNAMURTI, FAGAN_BRADLEY, SRI_YUKTESHWAR and LAHARI are accepted for KP, FAGAN, YUKTESHWAR and LAHIRI too. SIDM_USER needs ayanamsa_value. Any other value is rejected with 422.
ayanamsa_valuenumberNonullYour own ayanamsa in degrees, -30.0 to 30.0, used with ayanamsa_mode SIDM_USER. SIDM_USER without a value is rejected with 422.
Example request
curl -X POST "https://jagannatha-hora-359167915530.europe-west1.run.app/surya-siddhanta" \
  -H "content-type: application/json" \
  -d '{
    "date": "1990-01-01", "time": "06:30:00",
    "latitude": 12.9716, "longitude": 77.5946, "timezone": 5.5
  }'
Example response (abridged; comments mark the cuts)
{
  "birth_details": {
    "date": "1990-01-01",
    "time": "06:30:00",
    "place": "",
    "latitude": 12.9716,
    "longitude": 77.5946,
    "elevation": 0.0,
    "timezone": 5.5,
    "timezone_used": 5.5,
    "timezone_derived": 5.5,
    "timezone_source": "derived"
  },
  "surya_siddhanta": {
    "method": { /* … */ },
    "epoch": { /* … */ },
    "ayanamsa": {
      "surya_siddhanta_value": 22.36122089532924,
      "requested_mode": "LAHIRI",
      "requested_value": 23.7174169601642,
      "delta_to_requested": 1.3561960648349611,
      "applied_to_longitudes": true
      /* … */
    },
    "lagna": {
      "sign": "Sagittarius",
      "degrees_in_sign": 11.339549808982099,
      "nakshatra": "Mula",
      "pada": 4
      /* … */
    },
    "planets": {
      "Sun": {
        "sign": "Sagittarius",
        "degrees_in_sign": 15.043911393583272,
        "nakshatra": "Purva Ashadha",
        "pada": 1,
        "daily_motion": 1.0239181633529029,
        "retrograde": false
        /* … */
      }
      /* …the other eight bodies */
    },
    "panchanga": {
      "tithi": {
        "name": "Chaturthi",
        "paksha": "Shukla",
        "ends_at_local": "08:08:39"
      },
      "vaara": { "index": 1, "name": "Monday" }
      /* … */
    }
  }
}
  • surya_siddhanta holds method, epoch, ayanamsa, lagna, planets and panchanga.
  • The same chart is available inside POST /horoscope as horoscope.surya_siddhanta when you send calculation_type "ss".

POST/marriage-match

Ashtakoota (North Indian) and 10 Porutham (South Indian) compatibility for two charts.

Takes two birth charts and scores them under both classical systems at once, then adds the dosha scores for each person and the Beeja and Kshetra rasi. The North Indian block scores the eight kootas out of 36 and adds four further poruthams; the South Indian block reports each of the ten poruthams as matched or not, with the minimum-porutham flag. Each block also carries the classical rating band for its score (for example "Good" or "Poor"); it is a score band, not advice.

Rate limit
30 requests/minute per IP
Authentication
None. Open endpoint, no key required.
Response keys
boy, girl, north_indian, south_indian, boy_dosha_data, girl_dosha_data, beeja_rasi, kshetra_rasi, engine_revision
Body fields for /marriage-match
ParameterTypeRequiredDefaultNotes
boy_birth_detailsobjectYes—date, time, latitude, longitude and timezone (all required) and elevation (default 0.0). No place field and no calculation settings.
girl_birth_detailsobjectYes—Same shape as boy_birth_details.
Fields of each person object in /marriage-match
ParameterTypeRequiredDefaultNotes
datestringYes—Birth date, YYYY-MM-DD. Year 1800-2100.
timestringYes—Birth time, HH:MM:SS (24-hour).
latitudenumberYes—-90 to 90. Birth places beyond about 66.5° north or south (inside the polar circles) are rejected with 422.
longitudenumberYes—-180 to 180.
timezonenumberYes—UTC offset at birth in hours, -12 to 14. The API works out the historically correct offset, daylight saving included, from the coordinates and date, and uses this value only where no time zone is known for the place.
elevationnumberNo0.0Metres above sea level.
Example request
curl -X POST "https://jagannatha-hora-359167915530.europe-west1.run.app/marriage-match" \
  -H "content-type: application/json" \
  -d '{
    "boy_birth_details": {
      "date": "1990-01-01", "time": "06:30:00",
      "latitude": 12.9716, "longitude": 77.5946, "timezone": 5.5
    },
    "girl_birth_details": {
      "date": "1992-03-15", "time": "14:20:00",
      "latitude": 13.0827, "longitude": 80.2707, "timezone": 5.5
    }
  }'
Example response (abridged; comments mark the cuts)
{
  "boy": {
    "nakshatra_number": 23,
    "nakshatra_name": "Dhanishta",
    "pada_number": 4,
    "raasi_number": 11,
    "raasi_name": "Kumbam"
  },
  "girl": {
    "nakshatra_number": 8,
    "nakshatra_name": "Pushya",
    "pada_number": 4,
    "raasi_number": 4,
    "raasi_name": "Katakam"
  },
  "north_indian": {
    "match_system": "North Indian (Ashtakoota)",
    "eight_koota_porutham": { /* …the eight kootas, each with score and max_score */ },
    "four_additional_porutham": { /* … */ },
    "overall_compatibility": {
      "total_score": 3.0,
      "max_possible_score": 36,
      "percentage": 8.33,
      "rating": "Poor"
    }
  },
  "south_indian": {
    "match_system": "South Indian (10 Porutham)",
    "ten_porutham": {
      "dina_porutham": true,
      "gana_porutham": false,
      "rajju_porutham": true
      /* …seven more */
    },
    "overall_compatibility": {
      "matched_count": 7,
      "total_porutham": 10,
      "percentage": 70.0,
      "rating": "Good",
      "minimum_porutham_satisfied": false
    }
  },
  "boy_dosha_data": {
    "mars_dosha": 30.0,
    "sun_dosha": 0.0,
    "saturn_dosha": 0.0,
    "rahu_ketu_dosha": 93.75,
    "total_dosha": 123.75
  },
  "girl_dosha_data": { /* …same shape */ },
  "beeja_rasi": "Dhanusu",
  "kshetra_rasi": "Kanni",
  "engine_revision": 6
}

POST/panchang

The full daily panchang for a date and place. No birth chart needed.

The five limbs — vaara, tithi, nakshatra, yoga, karana — with paksha, plus sun and moon rise and set, day length, the auspicious and inauspicious windows, day and night Choghadiya, the lunar month in both Amanta and Purnimanta reckoning, ritu, ayana, the Shaka, Vikrama and Kali years with the sixty-year cycle name, and the Moon and Sun signs. The response carries Cache-Control: public, max-age=21600.

Rate limit
60 requests/minute per IP
Authentication
None. Open endpoint, no key required.
Response keys
panchang
Body fields for /panchang
ParameterTypeRequiredDefaultNotes
datestringYes—YYYY-MM-DD; must be a real calendar date (2026-02-31 is rejected). Year 1800-2100.
latitudenumberYes—-90 to 90. Places beyond 66° north or south are rejected with 422, as is a date on which the Sun does not rise or set at the place.
longitudenumberYes—-180 to 180.
timezonenumberYes—UTC offset in hours, -12 to 14. The API works out the historically correct offset, daylight saving included, from the coordinates and date, and uses this value only where no time zone is known for the place.
placestringNo""Place name, echoed in the response as place.name.
ayanamsa_modestringNo"LAHIRI"One of the listed modes except SIDM_USER, case-insensitive; KRISHNAMURTI, FAGAN_BRADLEY, SRI_YUKTESHWAR and LAHARI are accepted for KP, FAGAN, YUKTESHWAR and LAHIRI too. Any other value is rejected with 422, SIDM_USER included, since no ayanamsa_value is taken here.
Example request
curl -X POST "https://jagannatha-hora-359167915530.europe-west1.run.app/panchang" \
  -H "content-type: application/json" \
  -d '{
    "date": "2026-10-03",
    "latitude": 12.9716, "longitude": 77.5946, "timezone": 5.5
  }'
Example response (abridged; comments mark the cuts)
{
  "panchang": {
    "date": "2026-10-03",
    "place": {
      "name": "",
      "latitude": 12.9716,
      "longitude": 77.5946,
      "timezone": 5.5
    },
    "sunrise": "06:12",
    "sunset": "18:05",
    "moonrise": "00:06 (+1d)",
    "moonset": "12:23",
    "day_length": "11h 52m",
    "vaara": "Saturday",
    "paksha": "Krishna",
    "tithi": { "name": "Saptami", "number": 22, "rikta": false, "end": "08:00:45" },
    "nakshatra": { "name": "Ardra", "number": 6, "pada": 1, "end": "01:29:54 (+1d)" },
    "yoga": { "name": "Variyana", "number": 18, "auspicious": true },
    "karana": { "name": "Bava", "number": 44 },
    "auspicious": {
      "abhijit_muhurta": { "start": "11:44", "end": "12:32" }
      /* …brahma_muhurta, vijaya_muhurta, godhuli_muhurta, amrit_kalam, nishita_muhurta */
    },
    "inauspicious": {
      "rahu_kalam": { "start": "09:10", "end": "10:39" }
      /* …yamaganda, gulika_kalam, durmuhurtam, varjyam */
    },
    "choghadiya": {
      "day": [
        {
          "name": "Kaala",
          "quality": "bad",
          "start": "06:12",
          "end": "07:41"
        }
        /* …seven more */
      ],
      "night": [/* … */]
    },
    "month": { "amanta": "Bhadrapada", "purnimanta": "Ashwina", "adhika": false },
    "ritu": "Varsha",
    "ayana": "Dakshinayana",
    "samvat": {
      "shaka": 1948,
      "vikrama": 2083,
      "kali": 5127,
      "samvatsara_name": "Parabhava"
    },
    "signs": {
      "moon": { "name": "Gemini", "number": 3 },
      "sun": { "name": "Virgo", "number": 6 }
    }
  }
}
  • Rahu Kalam is under inauspicious.rahu_kalam and the Abhijit muhurta under auspicious.abhijit_muhurta. Times are local to the place; "(+1d)" marks a time on the next day.

POST/gochar

Planetary positions for a date and place. No birth chart needed.

The nine grahas with sign and degree, nakshatra and pada, retrograde and combust flags, classical dignity (exalted, debilitated, moolatrikona, own, or null), speed in degrees per day, and when each next changes sign, nakshatra and pada — plus highlights with the Moon and Sun signs and the planets currently retrograde. Positions are geocentric and so the same worldwide at an instant; the place's timezone decides what counts as that date and how the times are shown. The response carries Cache-Control: public, max-age=21600.

Rate limit
60 requests/minute per IP
Authentication
None. Open endpoint, no key required.
Response keys
gochar
Body fields for /gochar
ParameterTypeRequiredDefaultNotes
datestringYes—YYYY-MM-DD; must be a real calendar date. Year 1800-2100.
latitudenumberYes—-90 to 90. No polar restriction.
longitudenumberYes—-180 to 180.
timezonenumberYes—UTC offset in hours, -12 to 14. The API works out the historically correct offset, daylight saving included, from the coordinates and date, and uses this value only where no time zone is known for the place.
placestringNo""Place name, echoed in the response as place.name.
ayanamsa_modestringNo"LAHIRI"One of the listed modes except SIDM_USER, case-insensitive; KRISHNAMURTI, FAGAN_BRADLEY, SRI_YUKTESHWAR and LAHARI are accepted for KP, FAGAN, YUKTESHWAR and LAHIRI too. Any other value is rejected with 422, SIDM_USER included, since no ayanamsa_value is taken here.
Example request
curl -X POST "https://jagannatha-hora-359167915530.europe-west1.run.app/gochar" \
  -H "content-type: application/json" \
  -d '{
    "date": "2026-10-03",
    "latitude": 12.9716, "longitude": 77.5946, "timezone": 5.5
  }'
Example response (abridged; comments mark the cuts)
{
  "gochar": {
    "date": "2026-10-03",
    "place": {
      "name": "",
      "latitude": 12.9716,
      "longitude": 77.5946,
      "timezone": 5.5
    },
    "planets": [
      {
        "planet": "Jupiter",
        "sign": "Cancer",
        "sign_number": 4,
        "degree": 25.7672,
        "nakshatra": "Ashlesha",
        "pada": 3,
        "retrograde": false,
        "combust": false,
        "dignity": "exalted",
        "speed_deg_per_day": 0.175,
        "sign_until": "2026-10-31 11:17",
        "nakshatra_until": "2026-10-31 11:17",
        "pada_until": "2026-10-08 17:41"
      },
      {
        "planet": "Saturn",
        "sign": "Pisces",
        "sign_number": 12,
        "degree": 17.1632,
        "nakshatra": "Revati",
        "pada": 1,
        "retrograde": true,
        "combust": false,
        "dignity": null,
        "speed_deg_per_day": -0.0787,
        "sign_until": "2027-06-03 04:05",
        "nakshatra_until": "2026-10-09 19:42",
        "pada_until": "2026-10-09 19:42"
      }
      /* …the other seven */
    ],
    "highlights": {
      "moon_sign": "Gemini",
      "sun_sign": "Virgo",
      "retrograde": ["Saturn", "Rahu", "Ketu"]
    }
  }
}
  • sign_until, nakshatra_until and pada_until are local date-times, "YYYY-MM-DD HH:MM".

POST/gochar/events

Transit events over a date range. No birth chart needed.

One date-sorted list of sign changes for every requested planet, nakshatra changes for all of them except the Moon (which changes nakshatra roughly daily), and retrograde stations for Mars, Mercury, Jupiter, Venus and Saturn. Each event has a type — "sign", "nakshatra" or "retrograde" — and a local date-time; sign and nakshatra events carry from, to and direction, and stations carry motion ("turns_retrograde" or "turns_direct"). The response carries Cache-Control: public, max-age=21600.

Rate limit
60 requests/minute per IP
Authentication
None. Open endpoint, no key required.
Response keys
gochar_events
Body fields for /gochar/events
ParameterTypeRequiredDefaultNotes
from_datestringYes—Range start, YYYY-MM-DD; a real calendar date.
to_datestringYes—Range end, YYYY-MM-DD. Must be after from_date and at most 90 days later, or the response is 400.
latitudenumberYes—-90 to 90. Used for the display timezone.
longitudenumberYes—-180 to 180.
timezonenumberYes—UTC offset in hours, -12 to 14, for expressing event times. The API works out the offset from the coordinates where it can; this value is the fallback.
placestringNo""Place name. Not used in the calculation.
planetsstring[]NonullPlanet names. Defaults to all nine: Sun, Moon, Mars, Mercury, Jupiter, Venus, Saturn, Rahu, Ketu. An unknown name is a 400.
ayanamsa_modestringNo"LAHIRI"One of the listed modes except SIDM_USER, case-insensitive; KRISHNAMURTI, FAGAN_BRADLEY, SRI_YUKTESHWAR and LAHARI are accepted for KP, FAGAN, YUKTESHWAR and LAHIRI too. Any other value is rejected with 422, SIDM_USER included, since no ayanamsa_value is taken here.
Example request
curl -X POST "https://jagannatha-hora-359167915530.europe-west1.run.app/gochar/events" \
  -H "content-type: application/json" \
  -d '{
    "from_date": "2026-10-01", "to_date": "2026-10-31",
    "latitude": 12.9716, "longitude": 77.5946, "timezone": 5.5
  }'
Example response (abridged; comments mark the cuts)
{
  "gochar_events": {
    "range": { "from": "2026-10-01", "to": "2026-10-31" },
    "timezone": 5.5,
    "ayanamsa_mode": "LAHIRI",
    "planets": [
      "Sun",
      "Moon",
      "Mars",
      "Mercury",
      "Jupiter",
      "Venus",
      "Saturn",
      "Rahu",
      "Ketu"
    ],
    "events": [
      {
        "type": "nakshatra",
        "planet": "Mercury",
        "from": "Chitra",
        "to": "Swati",
        "date": "2026-10-01 09:20",
        "direction": "forward"
      },
      {
        "type": "sign",
        "planet": "Moon",
        "from": "Taurus",
        "to": "Gemini",
        "date": "2026-10-02 15:41",
        "direction": "forward"
      },
      {
        "type": "retrograde",
        "planet": "Venus",
        "date": "2026-10-03 12:05",
        "motion": "turns_retrograde"
      }
      /* …20 more */
    ]
  }
}

POST/gochara

Transits for one target date, read against a birth chart.

The natal counterpart to /gochar. Returns the target moment and place, a short natal reference (Moon and lagna), the panchanga for the target moment, the muhurta windows (sunrise, sunset, solar noon, Abhijit with its clean sub-windows, and the Rahu, Gulika and Yamaganda periods), all nine planets with their house from the natal Moon and Lagna, and the person-relative strengths — Tara Bala from Moon, Sun and Lagna, Chandra Bala and Sade Sati state. The optional sections add ashtakavarga bindus and gochara-phala with vedha to each planet, and the D-1 and D-9 transit charts. The event location defaults to the birth location.

Rate limit
60 requests/minute per IP
Authentication
None. Open endpoint, no key required.
Response keys
birth_details, gochara

Takes the natal block, plus:

Body fields for /gochara
ParameterTypeRequiredDefaultNotes
node_typestringNo"mean"Rahu/Ketu as the "mean" or "true" node. Any value other than "true" gives the mean node.
timezone_modestringNo"auto""auto" works out the birth offset from the coordinates and date; "file" uses the birth timezone exactly as sent. Any other value is rejected with 422.
target_datestringYes—The date to read transits for, YYYY-MM-DD. Year 1800-2100.
target_timestringNo"12:00:00"HH:MM:SS on the target date. Defaults to local noon.
event_placestringNonullName of the place the transits are read for. Defaults to the birth place.
event_latitudenumberNonull-90 to 90. Defaults to the birth latitude. A date on which the Sun does not rise or set at the place is rejected with 422.
event_longitudenumberNonull-180 to 180. Defaults to the birth longitude.
event_timezonenumberNonull-12 to 14. The API works out the offset from the event coordinates where it can; this value, or the birth timezone when it is omitted, is the fallback.
event_elevationnumberNonullMetres. Defaults to the birth elevation.
includestring[]NonullOptional sections: "ashtakavarga", "gochara_phala", "transit_charts". Omit the field for all three; pass [] for none, or a subset.
Example request
curl -X POST "https://jagannatha-hora-359167915530.europe-west1.run.app/gochara" \
  -H "content-type: application/json" \
  -d '{
    "date": "1990-01-01", "time": "06:30:00", "place": "Bengaluru",
    "latitude": 12.9716, "longitude": 77.5946, "timezone": 5.5,
    "target_date": "2026-10-03"
  }'
Example response (abridged; comments mark the cuts)
{
  "birth_details": {
    "date": "1990-01-01",
    "time": "06:30:00",
    "place": "Bengaluru",
    "latitude": 12.9716,
    "longitude": 77.5946,
    "timezone": 5.5
  },
  "gochara": {
    "target": {
      "date": "2026-10-03",
      "time": "12:00:00",
      "place": "Bengaluru",
      "latitude": 12.9716,
      "longitude": 77.5946,
      "timezone": 5.5,
      "ayanamsa_mode": "LAHIRI"
    },
    "natal_ref": {
      "moon_sign": "Aquarius",
      "moon_nakshatra": "Dhanishta",
      "lagna_sign": "Sagittarius",
      "lagna_degree": 13.0166,
      "lagna_pada": 4,
      "lagna_nakshatra": "Mula"
    },
    "panchanga": {
      "vara": "Saturday",
      "paksha": "Krishna",
      "tithi": {
        "name": "Ashtami",
        "number": 23,
        "rikta": false,
        "end": "05:52:50 (+1d)"
      },
      "nakshatra": { "name": "Ardra", "number": 6, "pada": 2, "end": "01:29:54 (+1d)" },
      "yoga": { "name": "Variyana", "number": 18, "auspicious": true },
      "karana": { "name": "Balava", "number": 45 }
    },
    "muhurta": {
      "sunrise": "06:12:23",
      "sunset": "18:04:52",
      "solar_noon": "12:08:37",
      "abhijit": { "start": "11:44:52", "end": "12:32:22" },
      "rahu_kalam": { "start": "09:10:30", "end": "10:39:34" }
      /* …abhijit_clean, recommended_time, abhijit_fully_blocked, gulika_kalam, yamaganda */
    },
    "planets": [
      {
        "planet": "Venus",
        "sign": "Libra",
        "degree": 14.2579,
        "nakshatra": "Swati",
        "pada": 3,
        "retrograde": false,
        "combust": false,
        "house_from_moon": 9,
        "house_from_lagna": 11,
        "sav_bindus": 36,
        "bav_bindus": 7,
        "gochara": {
          "favourable": true,
          "vedha_house": 11,
          "vedha_obstructed": false,
          "effective_favourable": true
        }
      }
      /* …the other eight */
    ],
    "person_strength": {
      "tarabala": {
        "from_moon": { "tara": "Sampat", "tara_index": 2, "favourable": true },
        "from_sun": { "tara": "Pratyak", "tara_index": 5, "favourable": false },
        "from_lagna": { "tara": "Sadhana", "tara_index": 6, "favourable": true }
      },
      "chandrabala": { "house_from_moon": 5, "favourable": false },
      "sade_sati": {
        "active": true,
        "phase": "phase3_setting",
        "saturn_house_from_moon": 2
      }
    },
    "transit_charts": { /* …D-1_rasi and D-9_navamsa at the target moment */ }
  }
}
  • gochara holds target, natal_ref, panchanga, muhurta, planets, person_strength and, by default, transit_charts.

POST/gochara/range

The same natal transit reading for every day in a range, in one call.

Built for the case where an AI agent should do the deciding. Returns, for each day, the panchanga, muhurta windows including the clean Abhijit, the nine planets with their house from the natal Moon and Lagna, and the person-relative strengths — with no scoring and no "best date" verdict, so the caller reasons over the raw data itself. Ashtakavarga bindus and gochara-phala with vedha are added to each planet unless you leave them out. Rahu and Ketu are always the mean node here.

Rate limit
30 requests/minute per IP
Authentication
None. Open endpoint, no key required.
Response keys
gochara_range

Takes the natal block, plus:

Body fields for /gochara/range
ParameterTypeRequiredDefaultNotes
from_datestringYes—First day, YYYY-MM-DD.
to_datestringYes—Last day, YYYY-MM-DD. At most 60 days counting both ends, and not before from_date, or the response is 400.
time_of_daystringNo"12:00:00"HH:MM:SS used on each day. Defaults to local noon.
event_placestringNonullName of the place the transits are read for. Defaults to the birth place.
event_latitudenumberNonull-90 to 90. Defaults to the birth latitude. A date on which the Sun does not rise or set at the place is rejected with 422.
event_longitudenumberNonull-180 to 180. Defaults to the birth longitude.
event_timezonenumberNonull-12 to 14. The API works out the offset from the event coordinates where it can; this value, or the birth timezone when it is omitted, is the fallback.
event_elevationnumberNonullMetres. Defaults to the birth elevation.
includestring[]NonullOptional sections per day: "ashtakavarga" and "gochara_phala". Omit the field for both; pass [] for the lean snapshot.
Example request
curl -X POST "https://jagannatha-hora-359167915530.europe-west1.run.app/gochara/range" \
  -H "content-type: application/json" \
  -d '{
    "date": "1990-01-01", "time": "06:30:00", "place": "Bengaluru",
    "latitude": 12.9716, "longitude": 77.5946, "timezone": 5.5,
    "from_date": "2026-10-01", "to_date": "2026-10-03"
  }'
Example response (abridged; comments mark the cuts)
{
  "gochara_range": {
    "range": { "from": "2026-10-01", "to": "2026-10-03" },
    "place": "Bengaluru",
    "ayanamsa_mode": "LAHIRI",
    "natal_ref": {
      "moon_sign": "Aquarius",
      "moon_nakshatra": "Dhanishta",
      "lagna_sign": "Sagittarius",
      "lagna_degree": 13.0166,
      "lagna_pada": 4,
      "lagna_nakshatra": "Mula"
    },
    "count": 3,
    "days": [
      {
        "date": "2026-10-01",
        "panchanga": {
          "vara": "Thursday",
          "tithi": {
            "name": "Panchami",
            "number": 20,
            "rikta": false,
            "end": "12:36:19"
          }
          /* … */
        },
        "muhurta": { /* … */ },
        "planets": [
          {
            "planet": "Moon",
            "sign": "Taurus",
            "degree": 13.5421,
            "nakshatra": "Rohini",
            "pada": 2,
            "retrograde": false,
            "combust": false,
            "house_from_moon": 4,
            "house_from_lagna": 6,
            "sav_bindus": 31,
            "bav_bindus": 5,
            "gochara": {
              "favourable": false,
              "vedha_house": null,
              "vedha_obstructed": false,
              "effective_favourable": false
            }
          }
          /* … */
        ],
        "person_strength": {
          "chandrabala": { "house_from_moon": 4, "favourable": false }
          /* … */
        }
      }
      /* …2026-10-02 and 2026-10-03 */
    ]
  }
}
  • Pass include: [] when you want the lean snapshot. Omitting the field is not the same thing: it gives you both optional sections.

POST/saturn-timeline

Sade Sati and Dhaiyya timing, with the classical relief share.

Returns the Moon sign, the Sade Sati cycle that is running today (or else the next one, or the most recent), its three phases, whether it is active and which phase today falls in, the months remaining, and — from Saturn's kakshya in the ashtakavarga — the classical relief share. dhaiyya reports whether a 4th or 8th-house Saturn transit from the Moon is running today, and nextCycle the next Sade Sati. detail "full" adds the month-by-month bands, the interruptions and the segments. This is computation, not interpretation.

Rate limit
60 requests/minute per IP
Authentication
None. Open endpoint, no key required.
Response keys
saturn_timeline
Body fields for /saturn-timeline
ParameterTypeRequiredDefaultNotes
datestringYes—Birth date, YYYY-MM-DD. Year 1800-2100.
timestringYes—Birth time, HH:MM:SS (24-hour).
placestringNo""Birth place name. Not used in the calculation.
latitudenumberYes—-90 to 90. Birth places beyond about 66.5° north or south (inside the polar circles) are rejected with 422.
longitudenumberYes—-180 to 180.
timezonenumberYes—UTC offset at birth in hours, -12 to 14, used exactly as sent.
ayanamsa_modestringNo"LAHIRI""LAHIRI" or "RAMAN" only on this endpoint, case-insensitive; LAHARI is accepted for LAHIRI too. Anything else is rejected with 422.
detailstringNo"summary""summary" or "full". Anything else is rejected with 422.
Example request
curl -X POST "https://jagannatha-hora-359167915530.europe-west1.run.app/saturn-timeline" \
  -H "content-type: application/json" \
  -d '{
    "date": "1990-01-01", "time": "06:30:00", "place": "Bengaluru",
    "latitude": 12.9716, "longitude": 77.5946, "timezone": 5.5
  }'
Example response
{
  "saturn_timeline": {
    "moonSign": "Aquarius",
    "moonDegree": 303.39394884620714,
    "sadeSati": {
      "active": true,
      "currentPhase": "2nd",
      "cycle": {
        "startDate": "2020-01-24",
        "endDate": "2028-02-23",
        "phases": [
          {
            "sign": "Capricorn",
            "house": "12th",
            "startDate": "2020-01-24",
            "endDate": "2023-01-17"
          },
          {
            "sign": "Aquarius",
            "house": "1st",
            "startDate": "2023-01-17",
            "endDate": "2025-03-29"
          },
          {
            "sign": "Pisces",
            "house": "2nd",
            "startDate": "2025-03-29",
            "endDate": "2028-02-23"
          }
        ]
      },
      "monthsRemaining": 17,
      "reliefShare": 0.2417
    },
    "dhaiyya": { "active": false, "kind": null, "startDate": null, "endDate": null },
    "nextCycle": { "startDate": "2049-03-06", "endDate": "2057-04-07" }
  }
}
  • active, currentPhase, monthsRemaining, dhaiyya and which cycle is reported are worked out against today's date, so the same request gives a different answer over time. The example was computed on 2026-10-03.
  • moonSign is a sign name and moonDegree the Moon's sidereal longitude, 0-360.

POST/planet-ingress

Every sidereal sign change for a set of planets across a date range.

Includes retrograde back-outs and re-entries. Each crossing carries its local date-time ("YYYY-MM-DD HH:MM"), the signs it leaves and enters, a retrograde flag, a direction ("forward" or "retrograde"), and final_settling, which marks the last crossing of each sign boundary inside the window, so you can tell a temporary ingress from the one that sticks.

Rate limit
60 requests/minute per IP
Authentication
None. Open endpoint, no key required.
Response keys
planet_ingress
Body fields for /planet-ingress
ParameterTypeRequiredDefaultNotes
planetsstring[]NonullPlanet names. Defaults to Saturn, Jupiter, Rahu and Ketu. An unknown name is a 400.
from_datestringYes—Range start, YYYY-MM-DD.
to_datestringYes—Range end, YYYY-MM-DD. Must be after from_date and at most about five years later (5 × 366 days), or the response is 400.
timezonenumberNo0.0UTC offset in hours, -12 to 14, that crossing times are expressed in, used exactly as sent. Defaults to UTC, not IST.
ayanamsa_modestringNo"LAHIRI"One of the listed modes except SIDM_USER, case-insensitive; KRISHNAMURTI, FAGAN_BRADLEY, SRI_YUKTESHWAR and LAHARI are accepted for KP, FAGAN, YUKTESHWAR and LAHIRI too. Any other value is rejected with 422, SIDM_USER included, since no ayanamsa_value is taken here.
Example request
curl -X POST "https://jagannatha-hora-359167915530.europe-west1.run.app/planet-ingress" \
  -H "content-type: application/json" \
  -d '{
    "from_date": "2026-10-01", "to_date": "2026-12-31",
    "timezone": 5.5
  }'
Example response
{
  "planet_ingress": {
    "range": { "from": "2026-10-01", "to": "2026-12-31" },
    "timezone": 5.5,
    "ayanamsa_mode": "LAHIRI",
    "planets": ["Saturn", "Jupiter", "Rahu", "Ketu"],
    "ingresses": [
      {
        "planet": "Jupiter",
        "from_sign": "Cancer",
        "to_sign": "Leo",
        "date": "2026-10-31 11:17",
        "retrograde": false,
        "direction": "forward",
        "final_settling": true
      },
      {
        "planet": "Rahu",
        "from_sign": "Aquarius",
        "to_sign": "Capricorn",
        "date": "2026-12-05 22:33",
        "retrograde": true,
        "direction": "retrograde",
        "final_settling": true
      },
      {
        "planet": "Ketu",
        "from_sign": "Leo",
        "to_sign": "Cancer",
        "date": "2026-12-05 22:33",
        "retrograde": true,
        "direction": "retrograde",
        "final_settling": true
      }
    ]
  }
}
  • timezone defaults to 0.0 (UTC). A crossing near local midnight will look like it is on the previous day unless you pass your own offset.

POST/muhurta

Score every day in a range for an event, against classical muhurta rules and the native's own chart.

Scores each day by the classical factors — vara, nakshatra, tithi, paksha — and by the person's strength on that day (Tara Bala, Chandra Bala, Sade Sati), per the rules for the chosen event type. Returns the rules applied, the weights used, and the days as candidates sorted by score, each with its factors, score and score_breakdown, any hard failures, the best windows (the clean Abhijit) and the Rahu, Gulika and Yamaganda windows to avoid. It ranks; it does not pick a date.

Rate limit
30 requests/minute per IP
Authentication
None. Open endpoint, no key required.
Response keys
muhurta

Takes the natal block, plus:

Body fields for /muhurta
ParameterTypeRequiredDefaultNotes
event_typestringYes—One of the six event types GET /muhurta/events lists. Any other value is rejected with 422.
from_datestringYes—Scan start, YYYY-MM-DD.
to_datestringYes—Scan end, YYYY-MM-DD. At most 90 days counting both ends, and not before from_date, or the response is 400.
event_placestringNonullName of the place the transits are read for. Defaults to the birth place.
event_latitudenumberNonull-90 to 90. Defaults to the birth latitude. A date on which the Sun does not rise or set at the place is rejected with 422.
event_longitudenumberNonull-180 to 180. Defaults to the birth longitude.
event_timezonenumberNonull-12 to 14. The API works out the offset from the event coordinates where it can; this value, or the birth timezone when it is omitted, is the fallback.
event_elevationnumberNonullMetres. Defaults to the birth elevation.
day_part_resolution_minutesintegerNo155 to 60; anything else is rejected with 422. Echoed in the response; it does not currently change the scoring, which reads each day at midday.
respect_inauspicious_windowsbooleanNotrueReport the Rahu, Gulika and Yamaganda windows to avoid.
Example request
curl -X POST "https://jagannatha-hora-359167915530.europe-west1.run.app/muhurta" \
  -H "content-type: application/json" \
  -d '{
    "date": "1990-01-01", "time": "06:30:00", "place": "Bengaluru",
    "latitude": 12.9716, "longitude": 77.5946, "timezone": 5.5,
    "event_type": "griha_pravesha_own",
    "from_date": "2026-10-05", "to_date": "2026-10-07"
  }'
Example response (abridged; comments mark the cuts)
{
  "muhurta": {
    "event_type": "griha_pravesha_own",
    "event_label": "Griha Pravesha (own / new house)",
    "range": { "from": "2026-10-05", "to": "2026-10-07" },
    "rules_applied": {
      "good_vara": ["Monday", "Wednesday", "Thursday", "Friday"],
      "avoid_vara": ["Tuesday", "Saturday", "Sunday"],
      "good_nakshatra": [
        "Rohini",
        "Mrigashira",
        "Chitra",
        "Anuradha",
        "Uttara Phalguni",
        "Uttara Ashadha",
        "Uttara Bhadrapada",
        "Revati",
        "Shatabhisha",
        "Dhanishta",
        "Swati",
        "Pushya"
      ],
      "require": ["tarabala_ok"],
      "prefer": ["chandrabala_ok", "shukla_paksha"]
      /* … */
    },
    "weights": {
      "base": 5,
      "vara": 15,
      "nakshatra": 20,
      "tithi": 15,
      "tarabala": 20,
      "chandrabala": 10,
      "shukla_paksha": 5,
      "clean_window": 10,
      "sade_sati_penalty": 10,
      "hard_fail_cap": 25
    },
    "day_part_resolution_minutes": 15,
    "candidates": [
      {
        "date": "2026-10-05",
        "vara": "Monday",
        "tithi": "Dashami",
        "nakshatra": "Pushya",
        "factors": {
          "vara": "Monday",
          "nakshatra": "Pushya",
          "tithi": "Dashami",
          "rikta": false,
          "vara_ok": true,
          "nakshatra_ok": true,
          "tithi_ok": true,
          "tarabala": "Kshema",
          "tarabala_ok": true,
          "chandrabala_ok": true,
          "shukla_paksha": false,
          "sade_sati": true,
          "has_clean_window": true
        },
        "score": 85,
        "score_breakdown": {
          "vara": 15,
          "nakshatra": 20,
          "tithi": 15,
          "tarabala": 20,
          "chandrabala": 10,
          "shukla_paksha": 0,
          "clean_window": 10,
          "sade_sati": -10
        },
        "hard_failed": [],
        "best_windows": [
          {
            "name": "abhijit_clean",
            "start": "12:08:01",
            "end": "12:31:43"
          }
        ],
        "avoid_windows": [
          { "name": "rahu_kalam", "start": "07:41:22", "end": "09:10:15" },
          {
            "name": "gulika_kalam",
            "start": "13:36:53",
            "end": "15:05:46"
          },
          { "name": "yamaganda", "start": "10:39:08", "end": "12:08:01" }
        ]
      }
      /* …2 more, by score */
    ]
  }
}

GET/muhurta/events

The event types POST /muhurta accepts.

The list of event_type values /muhurta accepts, each with a readable label and the classical basis of its rules. Today there are six: griha_pravesha_own, griha_pravesha_rented, travel_prayana, vehicle_purchase, business_shop_opening and property_purchase_registration.

Rate limit
None (not rate limited)
Authentication
None. Open endpoint, no key required.
Response keys
events
Example request
curl "https://jagannatha-hora-359167915530.europe-west1.run.app/muhurta/events"
Example response (abridged; comments mark the cuts)
{
  "events": [
    {
      "event_type": "griha_pravesha_own",
      "label": "Griha Pravesha (own / new house)"
    },
    {
      "event_type": "griha_pravesha_rented",
      "label": "Griha Pravesha (rented house)"
    }
    /* …4 more; each entry also has a source field */
  ]
}
  • Each entry has event_type, label and source.

Resolve a place name to coordinates and a timezone offset.

Resolves against an index of more than 162,000 world cities and returns the single best match. For "City, Country" inputs that do not match directly, the trailing part is dropped and the search retried, so "Springfield, IL, US" falls back to "Springfield, IL". Use it to turn a typed birth place into the latitude, longitude and timezone the calculation endpoints need.

Rate limit
None (not rate limited)
Authentication
None. Open endpoint, no key required.
Response keys
place, latitude, longitude, timezone, source, country, displayName, state (when known)
Query parameters for /location/search
ParameterTypeRequiredDefaultNotes
querystringNonullThe place name, at least 2 characters after trimming. Send query or q; with neither, or under 2 characters, the response is 400.
qstringNonullSame as query. If both are sent, query is used.
Example request
curl "https://jagannatha-hora-359167915530.europe-west1.run.app/location/search?query=Chennai,%20India"
Example response
{
  "place": "Chennai",
  "latitude": 13.0475,
  "longitude": 80.2087,
  "timezone": 5.5,
  "source": "database",
  "country": "India",
  "displayName": "Chennai, India"
}
  • timezone is the place's standard UTC offset (no daylight saving). The calculation endpoints work out historical, daylight-saving-aware offsets themselves where they can.
  • A miss is a 404 whose message suggests adding a country name or code.
  • The query is part of the URL. Send place names here, never birth dates or times.

GET/location/autocomplete

Place suggestions as the user types, from the same city index.

Matching places for a partial name, for populating a birth-place picker as the user types. Each result carries the place, country, state, a display name, coordinates, UTC offset and elevation.

Rate limit
None (not rate limited)
Authentication
None. Open endpoint, no key required.
Response keys
query, count, results
Query parameters for /location/autocomplete
ParameterTypeRequiredDefaultNotes
querystringNonullPartial place name, at least 2 characters. Send query or q; with neither, or under 2 characters, the response is 400.
qstringNonullSame as query. If both are sent, query is used.
limitintegerNo10Maximum results. Values above 50 are treated as 50.
Example request
curl "https://jagannatha-hora-359167915530.europe-west1.run.app/location/autocomplete?query=Benga&limit=3"
Example response (abridged; comments mark the cuts)
{
  "query": "Benga",
  "count": 3,
  "results": [
    {
      "place": "Bengaluru",
      "country": "India",
      "displayName": "Bengaluru, Karnataka, India",
      "latitude": 12.97194,
      "longitude": 77.59369,
      "timezone": 5.5,
      "elevation": 914,
      "state": "Karnataka"
    },
    {
      "place": "Kolkata",
      "country": "India",
      "displayName": "Kolkata, West Bengal, India",
      "latitude": 22.56263,
      "longitude": 88.36304,
      "timezone": 5.5,
      "elevation": 11,
      "state": "West Bengal"
    }
    /* …1 more */
  ]
}

GET/health

Health check.

Returns 200 with status "healthy" when the API is up. Use it for uptime checks.

Rate limit
None (not rate limited)
Authentication
None. Open endpoint, no key required.
Response keys
status, service
Example request
curl "https://jagannatha-hora-359167915530.europe-west1.run.app/health"
Example response (abridged; comments mark the cuts)
{
  "status": "healthy"
  /* …and a service name */
}

What POST /horoscope actually returns

The response is { "birth_details": {...}, "horoscope": {...}, "engine_revision": ... }. The example above shows a truncated excerpt because the real payload is several megabytes of JSON — printing it would be useless to a human and worse than useless to a model. Instead, here are all 33 keys always present inside horoscope, in the order the response lists them.

calendar_info
Panchanga and calendar context for the birth moment
bhava_chart
House (bhava) placements under the selected bhava_madhya_method, in 12 slots arranged by sign: slot 0 = Aries … slot 11 = Pisces. House 1 is the slot of the lagna's sign (the one holding the string “Ascendantℒ”), house n is slot (lagna slot + n − 1) mod 12, and each slot lists the bodies in that house. A body's slot can differ from its own sign; read its sign from divisional_charts (D-1).
ayanamsa_value
The ayanamsa in degrees actually applied
julian_day
Julian day number of the birth moment
divisional_charts
23 vargas, D-1 to D-144, each body with sign and longitude
nakshatra_pada
Nakshatra, pada, lord and degrees-in-nakshatra per body
amsa_rulers
D-150 Nadiamsa amsa rulers across planets, lagnas and sphutas
yogas
Classical yoga screening, with a summary of how many were found
doshas
Manglik, Kala Sarpa and the other classical doshas
chara_karakas
The eight variable karakas (Atma, Amatya, …)
sahams
The 36 sahams (Arabic parts)
upagrahas
The 11 shadowy sub-planets
special_lagnas
Bhava, Hora, Ghati and the other special ascendants
house_varnadas
Varnada lagna per house, V1 to V12
graha_arudhas
Arudha padas computed from the grahas
surya_arudhas
Arudhas measured from the Sun
chandra_arudhas
Arudhas measured from the Moon
house_relationships
Argala and virodhargala between houses
planetary_states
Retrograde, combust, exalted, debilitated and related lists
shad_bala
The six-fold planetary strength
shad_bala_required
The minimum Shad Bala each planet, Sun to Saturn, needs
bhava_bala
House strength
other_bala
Harsha, pancha and dwadhasa vargeeya bala, plus ishta and kashta phala
vimsopaka_bala
Twenty-point varga strength
vaiseshikamsa_bala
Vaiseshikamsa strength
shashtiamsa_rulers
The D-60 shashtiamsa and its classical nature for the lagna and each planet
ashtakavarga
BAV, SAV, SoAV and prastara grids, with the pindas
arudha_padhas
Arudha padas for every divisional chart (note the spelling, with an h)
sphuta
The 14 sphutas
graha_dashas
Graha dasha systems, Vimshottari included
rasi_dashas
Rasi dasha systems, Chara and Narayana included
saturn_transits
Sade Sati plus 4th/8th-house Saturn transits from Moon and Lagna
longevity_prediction
Classical longevity reference computations with the combinations behind them

Two more keys appear only when they apply:

surya_siddhanta
The Surya Siddhanta chart, present when calculation_type is "ss"
request_notes
Present when a setting could not be applied as sent, saying what was used instead

Two of these carry most of the weight. divisional_charts holds all 23 vargas keyed as D-1_rasi through D-144_dwadas_dwadasamsa, each mapping every body to a sign and a longitude. graha_dashas and rasi_dashas hold the timing systems. If you only need one of these, the MCP server has a tool per section and will not make you download the rest.

Note the spelling of arudha_padhas, with an h: the API returns the key exactly that way.

Errors

Errors come back as JSON. Most carry a detail field: a list of problems for a validation 422, a string otherwise. A 429 is the exception, with an error field instead. The message names the field and the constraint it broke, so it is worth surfacing to your users rather than swallowing.

400 Bad Request
Input the endpoint could not use. A well-formed request the calculation cannot serve: a date range that is too long or ends before it starts, an unknown planet name, a /location/search or /location/autocomplete query under 2 characters, or a /surya-siddhanta latitude beyond 66° north or south. detail is a string, often starting "Invalid input:".
404 Not Found
No location matched. GET /location/search found no place for the query. The message suggests adding a country name or code.
422 Unprocessable Entity
Validation failed. A required field is missing, has the wrong type, is out of range or is not one of the allowed values. detail is a list with one entry per problem, each carrying type, loc (where the field is), msg, input and ctx. Two further 422s carry a plain-string detail: a birth place inside the polar circles (beyond about 66.5° north or south), and a date on which the Sun does not rise or set at the place.
429 Too Many Requests
Rate limited. The endpoint's per-minute limit was exceeded for your IP address. The body is {"error": "Rate limit exceeded: 30 per 1 minute"}: an error field, not detail.
500 Internal Server Error
Calculation failed. An unexpected error while computing the result.
A validation failure (/panchang with latitude 70)
HTTP/1.1 422 Unprocessable Entity

{
  "detail": [
    {
      "type": "value_error",
      "loc": ["body", "latitude"],
      "msg": "Value error, latitude beyond +/-66 deg is unsupported for panchang (polar region)",
      "input": 70.0,
      "ctx": { "error": {} }
    }
  ]
}
An input the endpoint could not use (/location/search?query=a)
HTTP/1.1 400 Bad Request

{"detail": "Query must be at least 2 characters"}

Before you build on this

  • There is no versioned URL prefix and no deprecation policy today. The shapes documented here are the shapes the API returns, but a breaking change would not announce itself with a new path. engine_revision tells you when calculated values change.
  • There is no uptime SLA, no support contract and no status page.
  • The API returns classical computation, not advice. Labels such as a match's rating band or a window marked auspicious are the classical classification of the computed values; how much weight to give them is your judgement, or your model's.